通过bash脚本向/bin/bash传递参数

6
我正在编写一个bash脚本,它接受一些命令行参数(可能包含空格),并通过登录shell将它们全部传递给一个程序(/bin/some_program)。从bash脚本调用的登录shell将取决于用户的登录shell。在这个例子中,假设用户使用/bin/bash作为他们的登录shell...但它也可能是/bin/tcsh或其他任何东西。
如果我知道要传递给some_program的参数数量,我可以在我的bash脚本中放入以下几行:
#!/bin/bash
# ... (some lines where we determine that the user's login shell is bash) ...
/bin/bash --login -c "/bin/some_program \"$1\" \"$2\""

然后按照以下方式调用上述脚本:
my_script "this is too" cool

通过上面的例子,我可以确认some_program接收了两个参数,“this is too”和“cool”。

我的问题是……如果我不知道将传递多少个参数怎么办?我想把发送给my_script的所有参数都传递给some_program。问题是我无法弄清楚如何做到这一点。以下是一些行不通的方法:

/bin/bash --login -c "/bin/some_program $@"     # --> 3 arguments: "this","is","too"
/bin/bash --login -c /bin/some_program "$@"     # --> passes no arguments
2个回答

9
引用bash手册中有关-c的内容:

如果存在-c选项,则从字符串中读取命令。如果在字符串后面有参数,则将它们分配给位置参数,从$0开始

我已经理解了:
$ cat x.sh
#!/bin/bash
/bin/bash --login -c 'echo 1:$1 2:$2 3:$3' echo "$@"
$ ./x.sh "foo bar" "baz" "argh blargh quargh"
1:foo bar 2:baz 3:argh blargh quargh

我不知道你是如何得出“不传递参数”的结论的,也许你忽略了$ 0 部分?

3
避免将变量嵌入其他脚本中,而应该将它们作为参数传递。在这种情况下:
bash --login -c 'some_program "$@"' some_program "$@"

-c '...'后面的第一个参数被视为$0,所以我只是在那里放了一些程序。

顺便说一句,要求使用登录shell很奇怪。用户不是已经登录了吗?


我错过了$0部分,谢谢!非常感激。如果指向some_program的路径也存储在变量中(比如$cmd),那么该如何格式化呢?此外,你关于登录shell部分的正确性是对的...那实际上并不必要。 - JCOidl
@JCOidl bash -c '"$@"' _ "$cmd" "$@" 虽然如果不需要登录 shell,那么也无需调用新的 bash 实例,只需在当前脚本中运行即可。"$cmd" "$@" - geirha
我不理解这里的下划线符号表示什么。我之所以没有简单地使用 "$cmd" "$@" 是因为该脚本是从一个需要访问用户环境的OSX程序中调用的。因此,在某些情况下,我将不得不调用/bin/tcsh、/bin/ksh等。 - JCOidl
@JCOidl 我只是用 _ 代替了 some_command 来缩短它。$0 没有被使用。然而,用户的环境应该在用户登录时加载,并由此后的所有进程继承,所以我不明白你的观点。 - geirha
是的...这很令人困惑。OSX将环境变量对GUI应用程序可用与对从终端启动的UNIX类型程序可用的环境变量分开。因此,登录GUI不会自动加载在.profile或.cshrc中设置的环境,或者与用户默认shell相对应的任何内容。无论如何,即使将程序名称(或$cmd)替换为下划线,结果也会出现“找不到命令”的错误。PS-感谢您在这里的来回交流。这非常有用。 - JCOidl
@JCOidl 尝试加载交互式登录 shell,对于人类所知道的每个 shell 都进行加载可能是很费力的,而且大多数情况下从一个 shell 到另一个 shell 也不同。难道向用户传授正确设置环境变量的方法不是更好的选择吗?https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/EnvironmentVars.html - geirha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接