我有一个脚本tempenv
,我想使用如下:
$ tempenv ls -l
tempenv
看起来像这样:
#!/bin/bash
setarch ... /bin/bash -c $@
但是,它并没有按照我的预期工作。相反,它只运行第一个参数,忽略其他任何内容。那是tempenv ls -l
奔跑般的tempenv ls
。
答案1
man bash
:
-c
如果存在 -c 选项,则从第一个非选项参数 command_string 读取命令。如果 command_string 之后有参数,则第一个参数将分配给 $0,任何剩余参数将分配给位置参数。对 $0 的赋值设置了 shell 的名称,该名称用于警告和错误消息。
tempenv () { bash -c 'set -x; : "$@"' foo "$@"; }
tempenv ls -l 'foo bar'
+ : ls -l 'foo bar'
所以这对你有用:
#!/bin/bash
setarch ... /bin/bash -c '"$@"' tempenv-subshell "$@"
答案2
shell 的-c
选项需要将命令行作为一个参数,然后$@
将其一分为ls -l
二。 (也是如此"$@"
,只是它会保持带有空格的参数字符串完整,所以它也没有直接帮助。)
因此,假设您想传递一个实际的命令行,您必须只将一个字符串传递给脚本,然后使用 传递它sh -c "$1"
,或者如果您愿意,将脚本的所有参数连接到一个字符串中,然后使用sh -c "$*"
,即
#!/bin/bash
setarch ... /bin/bash -c "$*"
看:
这将支持在命令行中包含所有 shell 语法,例如
tempenv 'ls -l; echo $SOMEVAR'
tempenv '[ some test ] && echo true'
但另一方面,应该包含空格的参数,例如带有空格的文件名,需要引用两次,例如
tempenv 'ls -l "Some Document.txt"'
答案3
假设您将tempenv
脚本调用为tempenv ls -l
,即向其传递两个参数:命令名称和该命令的参数,听起来您实际上想要:
#!/bin/sh -
exec setarch ... "$@"
也就是说,您希望tempenv
在不同的架构下使用给定的参数运行给定的命令。
如果您确实希望它有一些 shell 在该不同的体系结构下解释某些代码,那么您可以将其称为tempenv 'ls -l'
由ls -l
您选择的 shell 解释的代码。其代码如下所示:
#! /bin/sh -
if [ "$#" -ne 1 ]; then
printf >&2 '%s\n' "Usage: $0 <code-in-bash-language>"
exit 1
fi
bash_code=$1
exec setarch ... /bin/bash -c -- "$bash_code"