如何通过另一个 shell 运行所有命令行参数?

如何通过另一个 shell 运行所有命令行参数?

我有一个脚本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"

相关内容