gpt4 book ai didi

bash - 在 bash 字符串变量中扩展花括号和通配符(不带 eval)

转载 作者:行者123 更新时间:2023-12-04 03:48:13 24 4
gpt4 key购买 nike

bash 中给定一个字符串变量(不是字符串),如何展开它的大括号(并全局匹配星号等任何文件通配符),然后存储导致数组扩展?

我知道这可以通过 eval 实现:

#!/usr/bin/env bash

string="{a,b}{1,2}"
array=( $( eval echo $string ) )
echo "${array[@]}"
#a1 a2 b1 b2

但是如果我们不信任 string 的内容(例如,如果它是脚本的参数),eval 可能会很危险。嵌入分号、引号、空格、任意命令等的 string 可以打开脚本进行攻击。

有没有更安全的方法在 bash 中进行这种扩展?我怀疑以下所有扩展字符串的方式同样不安全:

#!/usr/bin/env bash

eval echo $string

bash <<< "echo $string"

echo echo $string | bash

bash <(echo echo $string)

除了 bash 之外,我们是否可以通过管道将字符串传递给其他命令来进行扩展?

旁白:请注意,在 csh/tcsh 中这很容易,因为大括号扩展发生在之后 变量替换(与 bash 不同):

#!/usr/bin/env csh

set string = "{a,b}{1,2}"
set array = ( $string )
echo "$array"
#a1 a2 b1 b2

最佳答案

braceexpand Python module ,结合标准库 glob 模块,可以用来完成你正在寻找的东西。包装在 shell 中以便从 bash 中使用,这可能看起来像:

#!/usr/bin/env bash
case $BASH_VERSION in
''|[123].*|4.[012].*) echo "ERROR: bash 4.3+ required" >&2; exit 1;;
esac

# store Python code in a string
expand_py=$(cat <<'EOF'
try:
import sys, glob, braceexpand
except ImportError as e:
sys.stderr.write("Did you remember to install the braceexpand Python module?\n")
raise e

for arg in sys.argv[1:]:
for globexp in braceexpand.braceexpand(arg):
glob_results = glob.glob(globexp)
if len(glob_results) == 0:
sys.stdout.write(globexp)
sys.stdout.write('\0')
continue
else:
sys.stdout.write(''.join(['%s\0' % result for result in glob_results]))
EOF
)

# shell wrapper for the above Python program
expand() {
local item
local -n dest_array=$1; shift

dest_array=( )
while IFS= read -r -d '' item; do
dest_array+=( "$item" )
done < <(python3 -c "$expand_py" "$@")
unset -n dest_array
}

# actually demonstrate usage
expand yourArray '{a,b}{1,2}'
declare -p yourArray

...运行预期数组值时的输出:

declare -a yourArray=([0]="a1" [1]="a2" [2]="b1" [3]="b2")

关于bash - 在 bash 字符串变量中扩展花括号和通配符(不带 eval),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64810755/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com