Bash $(printf“%q'”${@:1})是否等于“${*}”?
$printf'%q'${@:1}是否等于${*} 如果它们是,那么就执行$printf'%q'${@:2}注意,使用纯bash$* 相关问题:Bash $(printf“%q'”${@:1})是否等于“${*}”?,bash,shell,arguments,parameter-passing,posix,Bash,Shell,Arguments,Parameter Passing,Posix,$printf'%q'${@:1}是否等于${*} 如果它们是,那么就执行$printf'%q'${@:2}注意,使用纯bash$* 相关问题: 不,它不是等价的,因为单词是分开的。例如,以下代码: check_args() { echo "\$#=$#" printf "%s\n" "$@"; } # setting arguments set -- "space notspace" "newline"$'\n'"newline" echo '1: ----------------
不,它不是等价的,因为单词是分开的。例如,以下代码:
check_args() {
echo "\$#=$#"
printf "%s\n" "$@";
}
# setting arguments
set -- "space notspace" "newline"$'\n'"newline"
echo '1: ---------------- "$*"'
check_args "$*"
echo '2: ---------------- $(printf '\''%q '\'' "${@:1}")'
check_args $(printf '%q ' "${@:1}")
echo '3: ---------------- "$(printf '\''%q '\'' "${@:1}")"'
check_args "$(printf '%q ' "${@:1}")"
echo '4: ---------------- IFS=@ and "$*"'
( IFS=@; check_args "$*"; )
echo "5: ---------------- duplicating quoted"
check_args "$(printf '%s'"${IFS:0:1}" "${@:1}" | sed 's/'"${IFS:0:1}"'$//')"
echo "6: ---------------- duplicating quoted IFS=@"
( IFS=@; check_args "$(printf '%s'"${IFS:0:1}" "${@:1}" | sed 's/'"${IFS:0:1}"'$//')"; )
echo "7: ---------------- duplicating eval unquoted"
eval check_args $(printf '%q"'"${IFS:0:1}"'"' "${@:1}" | sed 's/'"${IFS:0:1}"'$//')
echo "8: ---------------- duplicating eval unquoted IFS=@"
( eval check_args $(IFS=@ ; printf '%q"'"${IFS:0:1}"'"' "${@:1}" | sed 's/"'"${IFS:0:1}"'"$//'); )
将输出:
1: ---------------- "$*"
$#=1
space notspace newline
newline
2: ---------------- $(printf '%q ' "${@:1}")
$#=3
space\
notspace
$'newline\nnewline'
3: ---------------- "$(printf '%q ' "${@:1}")"
$#=1
space\ notspace $'newline\nnewline'
4: ---------------- IFS=@ and "$*"
$#=1
space notspace@newline
newline
5: ---------------- duplicating quoted
$#=1
space notspace newline
newline
6: ---------------- duplicating quoted IFS=@
$#=1
space notspace@newline
newline
7: ---------------- duplicating eval unquoted
$#=1
space notspace newline
newline
8: ---------------- duplicating eval unquoted IFS=@
$#=1
space notspace@newline
newline
经过测试
$*输出由IFS确定的参数。因此,如测试4所示,如果delimeter没有取消设置或设置为空格,那么在本例中,@的IFS将对$*的输出进行delimeter
另外,当IFS未设置或设置为空格时,$*的输出不包括终止空格,而printf“%q”将始终在字符串的末尾打印一个尾随空格
$printf'%q'${@:1}的输出仍在空间上拆分。因此,测试用例2接收3个参数,因为空格notspace字符串由空格分隔并拆分为两个参数。如果将printf封装在内部,则不会有任何帮助-printf用例如换行符代替\n字符
案例5、6、7、8是我尝试使用printf复制$*的行为。在我使用eval的案例7和案例8中可以看到,在案例5和案例6中,我引用了命令替换。案例5和6以及案例7和8的输出应分别与案例1和案例4的输出相匹配
为了复制$*的行为,需要特别注意IFS正确地测量字符串。我使用sed的/'${IFS:0:1}'$/'从printf输出中删除尾随的IFS分隔符。第5和第6个案例是未报价的$printf。。。尝试,6使用IFS=@显示分离的作品。第7和第8种情况使用eval对IFS进行特殊处理,因为IFS字符本身需要用引号括起来,所以shell不会在其上再次拆分,这就是为什么printf“%q”${IFS:0:1}”
执行$printf“%q”${@:2}注意,对于纯bash$*,不能像以前那样使用2而不是1
您可能只需要在替换$shift中转移参数;printf%s\n$*,但如上所示,它们无论如何都不是等价的。使用answer作为基础,我构建了这个新的测试代码,用于演示,还包括:
!/bin/bash
检查参数{
回音\$=$
本地计数器=0
对于var in$@
做
计数器=$计数器+1;
printf$counter.'$var';
完成
printf\\n\\n
}
设置参数
set-space-notspace-lastargument;计数器=1
echo$计数器“:-----------$*”;计数器=$counter+1
检查参数$*
echo$计数器“:-----------$*”;计数器=$counter+1
检查参数$*
echo$计数器“:-----------$@”;计数器=$counter+1
检查参数$@
echo$计数器“:-----------$@”;计数器=$counter+1
检查参数$@
echo$counter':----------$printf'\%q'\${@:1}';计数器=$counter+1
检查参数$printf'%q'${@:1}
echo$counter':----------$printf'\%q'\${@:1}';计数器=$counter+1
检查参数$printf'%q'${@:1}
echo$counter':-----------IFS=@和$*';计数器=$counter+1
如果=@;勾选_args$*;
echo$计数器------重复报价;计数器=$counter+1
检查_args$printf“%s”${IFS:0:1}${@:1}| sed的/'${IFS:0:1}'$/'
echo$计数器:---复制引用的IFS=@;计数器=$counter+1
如果=@;检查_args$printf“%s”${IFS:0:1}${@:1}| sed's/'${IFS:0:1}$/';
echo$计数器:---复制未报价的评估;计数器=$counter+1
评估检查参数$printf'%q'${IFS:0:1}'${@:1}| sed's/'${IFS:0:1}'$/'
echo$计数器:---复制评估未引用的IFS=@;计数器=$counter+1
评估检查参数$IFS=@;printf'%q'${IFS:0:1}'${@:1}| sed's/'${IFS:0:1}'$/';
->
为什么不试试看呢?使用更常用的${*}编写$*会产生一个字符串。POSIX没有为printf命令或printf函数指定%q转换规范。您必须参考您的系统的文档才能知道这将要做什么。
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
1: ---------------- "$*"
$#=1
1. 'space notspace lastargument',
2: ---------------- $*
$#=3
1. 'space', 2. 'notspace', 3. 'lastargument',
3: ---------------- "$@"
$#=2
1. 'space notspace', 2. 'lastargument',
4: ---------------- $@
$#=3
1. 'space', 2. 'notspace', 3. 'lastargument',
5: ---------------- $(printf '%q ' "${@:1}")
$#=3
1. 'space', 2. 'notspace', 3. 'lastargument',
6: ---------------- "$(printf '%q ' "${@:1}")"
$#=1
1. 'space\ notspace lastargument ',
7: ---------------- IFS=@ and "$*"
$#=1
1. 'space notspace@lastargument',
8: ---------------- duplicating quoted
$#=1
1. 'space notspace lastargument',
9: ---------------- duplicating quoted IFS=@
$#=1
1. 'space notspace@lastargument',
10: ---------------- duplicating eval unquoted
$#=1
1. 'space notspace lastargument ',
11: ---------------- duplicating eval unquoted IFS=@
$#=1
1. 'space notspace@lastargument',