ezp*_*zpz 23 bash quotes arguments function
我想要做的是,作为函数的输入,可以包括引号(单引号或双引号)和与该函数提供的行完全相同的回声.例如:
function doit {
printf "%s " ${@}
eval "${@}"
printf " # [%3d]\n" ${?}
}
Run Code Online (Sandbox Code Playgroud)
其中,给出以下输入
doit VAR=42
doit echo 'single quote $VAR'
doit echo "double quote $VAR"
Run Code Online (Sandbox Code Playgroud)
产量如下:
VAR=42 # [ 0]
echo single quote $VAR # [ 0]
echo double quote 42 # [ 0]
Run Code Online (Sandbox Code Playgroud)
所以变量扩展的语义就像我期望的那样得到保留,但是我无法得到提供给函数的行的确切格式.我想要的是doit echo 'single quote $VAR'结果echo 'single quote $VAR'.
我确信这与bash在传递给函数之前处理参数有关; 我只是想找个方法(如果可能的话).
所以我的目的是影响脚本的执行,同时提供执行的精确副本,可以用作诊断工具,包括每个步骤的退出状态.
虽然我可以通过做类似的事情来获得上述所需的行为
while read line ; do
doit ${line}
done < ${INPUT}
Run Code Online (Sandbox Code Playgroud)
面对控制结构(即等)if,这种方法失败了while.我考虑过使用set -x但是也有它的局限性:对于失败的命令,"变为'退出状态并且不可见.
Dav*_*ebb 11
我与你处于类似的位置,因为我需要一个脚本来包装现有命令并传递保持引用的参数.
我想出了一些不完全保存命令行的东西,但确实正确地传递了参数并告诉你它们是什么.
这是我设置为阴影的脚本ls:
CMD=ls
PARAMS=""
for PARAM in "$@"
do
PARAMS="${PARAMS} \"${PARAM}\""
done
echo Running: ${CMD} ${PARAMS}
bash -c "${CMD} ${PARAMS}"
echo Exit Code: $?
Run Code Online (Sandbox Code Playgroud)
这是一些示例输出:
$ ./shadow.sh missing-file "not a file"
Running: ls "missing-file" "not a file"
ls: missing-file: No such file or directory
ls: not a file: No such file or directory
Exit Code: 1
Run Code Online (Sandbox Code Playgroud)
因此,你可以看到它添加了原来不存在的引号,但它确实保留了带有空格的参数,而这正是我所需要的.
发生这种情况的原因是因为bash按照您的想法解释了这些参数.当它调用函数时,引号根本不再存在,所以这是不可能的.它在DOS下工作,因为程序可以自己解释命令行,而不是它可以帮助你!
尽管@Peter Westlake的答案是正确的,并且没有引号可以保留,但可以尝试推断引号是否需要并因此最初传入。就个人而言,requote当我需要在我的日志中证明命令以正确的引用运行时,我使用了这个函数:
function requote() {
local res=""
for x in "${@}" ; do
# try to figure out if quoting was required for the $x:
grep -q "[[:space:]]" <<< "$x" && res="${res} '${x}'" || res="${res} ${x}"
done
# remove first space and print:
sed -e 's/^ //' <<< "${res}"
}
Run Code Online (Sandbox Code Playgroud)
这是我如何使用它:
CMD=$(requote "${@}")
# ...
echo "${CMD}"
Run Code Online (Sandbox Code Playgroud)