jes*_*e_b 2 bash array shell-script
我有以下 bash 脚本:
#!/bin/bash
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 0,10 0,11 0,12 0,13 0,14 0,15 )
MISSING_DISKS=()
OLDIFS=$IFS
IFS=$'\n'
MISSING_DISKS+=($({ printf '0 %s\n' {0..15}; printf '0 %s\n' "${encl0[@]#0,}"; } | sort | uniq -u))
IFS=$OLDIFS
echo "$({ printf '0 %s\n' {0..15}; printf '0 %s\n' "${encl0[@]#0,}"; } | sort | uniq -u)"
echo "${MISSING_DISKS[@]}"
if ((${#MISSING_DISKS[@]}>1)); then
echo "Greater than 1"
else
echo "Success"
fi
Run Code Online (Sandbox Code Playgroud)
当我使用 bash v4.4 运行它时,它按我的预期工作:
$ /usr/local/bin/bash test.sh
0 6
0 6
Success
Run Code Online (Sandbox Code Playgroud)
但是,当我使用 bash v3.2 运行它时,它不会:
$ /bin/bash test.sh
0 6
0 0 0 0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 0 1 0 10 0 11 0 12 0 13 0 14 0 15 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9
Greater than 1
Run Code Online (Sandbox Code Playgroud)
我不明白如何MISSING_DISKS
设置与设置它的命令的输出不同的东西。有谁知道是什么原因造成的?
使用空格、制表符或换行符总是接近失败。
核心问题出现在这里:
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 )
IFS=$'\n'
printf '<0 %s>\n' "${encl0[@]#0,}"
Run Code Online (Sandbox Code Playgroud)
如果在 bash 3.2 上执行:
$ b32sh ./script
<0 0 1 2 3 4 5 7 8 9>
Run Code Online (Sandbox Code Playgroud)
的扩展"${encl0[@]#0,}"
被处理为一个字符串,而不是一个值列表。
如果 IFS 有空格或者扩展没有编辑数组的每个值,则问题不会出现:
#!/bin/bash
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 )
IFS=$' \n'
printf '<0 %s>\n' "${encl0[@]#0,}"
Run Code Online (Sandbox Code Playgroud)
执行:
$ b32sh ./script
<0 0>
<0 1>
<0 2>
<0 3>
<0 4>
<0 5>
<0 7>
<0 8>
<0 9>
Run Code Online (Sandbox Code Playgroud)
或者:
#!/bin/bash
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 )
IFS=$'\n'
printf '<0 %s>\n' "${encl0[@]}"
Run Code Online (Sandbox Code Playgroud)
执行:
b32sh ./so
<0 0,0>
<0 0,1>
<0 0,2>
<0 0,3>
<0 0,4>
<0 0,5>
<0 0,7>
<0 0,8>
<0 0,9>
Run Code Online (Sandbox Code Playgroud)
问题隐藏在您的脚本中,因为您IFS=$OLDIFS
在测试回声行之前恢复了 IFS 。
避免该问题的一种方法是不在 printf 中使用空格:
#!/bin/bash
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 0,10 0,11 0,12 0,13 0,14 0,15 )
MISSING_DISKS=()
OLDIFS=$IFS
IFS=$' \n'
MISSING_DISKS+=($({ printf '0x%s\n' {0..15}; printf '0x%s\n' "${encl0[@]#0,}"; } | sort | uniq -u))
echo "test $({ printf '0x%s\n' {0..15}; printf '0x%s\n' "${encl0[@]#0,}"; } | sort | uniq -u)"
echo "var ${MISSING_DISKS[@]}"
if ((${#MISSING_DISKS[@]}>1)); then
echo "Greater than 1"
else
echo "Success"
fi
IFS=$OLDIFS
Run Code Online (Sandbox Code Playgroud)
另一种选择是通过使用备用数组将 IFS 更改为换行符后避免使用替换进行扩展:
#!/bin/bash
OLDIFS=$IFS
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 0,10 0,11 0,12 0,13 0,14 0,15 )
IFS=$' \n'; arr=("${encl0[@]#0,}")
MISSING_DISKS=()
IFS=$'\n'
MISSING_DISKS+=($({ printf '0 %s\n' {0..15}; printf '0 %s\n' "${arr[@]}"; } | sort | uniq -u))
echo "test $({ printf '0 %s\n' {0..15}; printf '0 %s\n' "${arr[@]}"; } | sort | uniq -u)"
echo "var ${MISSING_DISKS[@]}"
if ((${#MISSING_DISKS[@]}>1)); then
echo "Greater than 1"
else
echo "Success"
fi
IFS=$OLDIFS
Run Code Online (Sandbox Code Playgroud)
我建议你:
+=
在代码中增加此时为空的数组MISSING_DISKS+=
。如果这些更改完成,脚本将变为:
#!/bin/bash
oldIFS=$IFS
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 0,10 0,11 0,12 0,13 0,14 0,15 )
unset missing_disks
IFS=' '
arr=($(printf '0-%s\n' "${encl0[@]#0,}"))
arr+=($(printf '0-%s\n' {0..15}))
missing_disks=($(printf '%s\n' "${arr[@]}" | sort | uniq -u))
echo "test $(printf '0-%s\n' "${arr[@]}" | sort | uniq -u)"
echo "var ${missing_disks[@]}"
((${#missing_disks[@]}>1)) && echo "Greater than 1" || echo "Success"
IFS=$oldIFS
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
231 次 |
最近记录: |