我有一个脚本 print.sh:
#!/bin/bash
echo printing provided args:
for i in "$@"; do
echo -e "\t${i}"
done
如果我在提示时执行此操作a=$(. print.sh ); echo "${a}"
,那么我会得到printing provided args:
存储的输出
我测试命令替换的主要脚本如下所示:
#!/bin/bash
function func_to_call_sub_scrp
{
# Call sub-script
capture="$(. $1 $2 $3)"
echo -e "captured output:
\t\t${capture}"
}
echo "Run function to call sub script without parameters passed. "
func_to_call_sub_scrp print.sh
echo ""
echo "Run function to call sub script with parameters passed."
func_to_call_sub_scrp print.sh xx yy
这输出:
Run function to call sub script without parameters passed.
captured output:
printing provided args:
print.sh
Run function to call sub script with parameters passed.
captured output:
printing provided args:
xx
yy
第二次调用将 xx 和 yy 发送到 print.sh,这符合预期。但是,当我发送“print.sh”“”“”命令替换时,将调用 print.sh 并将其作为 $1 发送 print.sh,而不是发送“”和“”
我的问题是,当没有其他输入时,如何将 $1 作为参数传递给打印脚本?我期望"$(. $1 $2 $3)"
成为"$(. print.sh )"
或"printing provided args:"
一旦回来。
答案1
请注意,你这样做不是. "print.sh" "" ""
在第一个示例中运行。您正在运行,. print.sh
因为您没有引用$2
或$3
。
从bash
手册中,关于source
(和.
),我强调:
[...] 如果提供任何参数,它们将在执行 filename 时成为位置参数。 否则位置参数不变。
当您调用 时. print.sh
,您不向点脚本提供参数print.sh
,因此位置参数保持不变。但它们是什么?
点脚本中的位置参数将在第一次调用时成为函数的位置参数,该函数是由单个 string 组成的列表print.sh
。这就是为什么"$@"
扩展到点print.sh
脚本内部的原因。
只是评论:
使用制表符缩进输出所有位置参数的更好方法:
printf '\t%s\n' "$@"
这避免了所echo
描述的问题别处。可以对$capture
函数中的输出方式进行类似的评论。
$1
您还需要引用、$2
和的扩展$3
,除非您希望 shell 在 中 的字符上拆分它们$IFS
并对结果单词应用文件名通配。看什么时候需要双引号?。