我的dash脚本采用 形式的参数hostname:port,即:
myhost:1234
Run Code Online (Sandbox Code Playgroud)
而端口是可选的,即:
myhost
Run Code Online (Sandbox Code Playgroud)
我需要将主机和端口读入单独的变量。在第一种情况下,我可以这样做:
HOST=${1%%:*}
PORT=${1##*:}
Run Code Online (Sandbox Code Playgroud)
但这在第二种情况下不起作用,当端口被省略时;echo ${1##*:}只返回主机名,而不是空字符串。
在 Bash 中,我可以这样做:
IFS=: read A B <<< asdf:111
Run Code Online (Sandbox Code Playgroud)
但这在dash.
能否在拆分字符串:在仪表板,而无需调用外部程序(awk,tr,等)?
Sté*_*las 18
做就是了:
case $1 in
(*:*) host=${1%:*} port=${1##*:};;
(*) host=$1 port=$default_port;;
esac
Run Code Online (Sandbox Code Playgroud)
您可能希望更改case $1tocase ${1##*[]]}以考虑$1like 的值[::1](没有端口部分的 IPv6 地址)。
要拆分,您可以使用split+glob运算符(不带引号的参数扩展),因为这毕竟是它的用途:
set -o noglob # disable glob part
IFS=: # split on colon
set -- $1 # split+glob
host=$1 port=${2:-$default_port}
Run Code Online (Sandbox Code Playgroud)
(尽管这不允许包含冒号的主机名(例如上面的 IPv6 地址))。
那个 split+glob 运算符会妨碍并在其余时间造成如此大的伤害,以至于在需要时使用它似乎是公平的(不过,我同意使用它非常麻烦,特别是考虑到 POSIXsh没有支持局部作用域,既不支持变量($IFS此处)也不支持选项(noglob此处)(尽管ash和派生类dash是其中的一些(与ksh,zsh和bash4.4 及更高版本的AT&T 实现一起))。
请注意,IFS=: read A B <<< "$1"它有一些自己的问题:
-r这意味着反斜杠将进行一些特殊处理。[::1]:443为[and:1]:443而不是[and 空字符串(为此您需要IFS=: read -r A B rest_ignoredor[::1]和443(为此您不能使用该方法)-d ''in zshorbash并且数据不包含 NUL 字符,但请注意 herestrings(或heredocs)确实添加了一个额外的换行符!)zsh(语法来自)和bash,这里的字符串是使用临时文件实现的,因此它通常比使用${x#y}或 split+glob 运算符效率低。只需:在单独的语句中删除;另外,从输入中删除 $host 以获取端口:
host=${1%:*}
port=${1#"$host"}
port=${port#:}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5382 次 |
| 最近记录: |