使用命令替换获取脚本时传递的参数错误

使用命令替换获取脚本时传递的参数错误

我有一个脚本 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并对结果单词应用文件名通配。看什么时候需要双引号?

相关内容