我有一个 shell 脚本(我在 Ubuntu 18.04 上使用 GNU bash 4.4.20),其中包含我经常运行的命令列表,例如:
sudo program1 $1 foo arg1
sudo program2 $1 foo arg2
sudo program1 $1 bar arg3
sudo program2 $1 bar arg4
我想 grep 查找此脚本中的选定行并运行它们。例如,如果我想运行上面的第 3 行和第 4 行并将 $1 设置为“some_value”,我认为类似下面的方法可行:
set some_value; grep bar my_shell_script.sh | xargs -L1
我认为我的问题是 1)如果命令本身嵌入在输入中,我不确定如何使用 xargs;2)如果它从 grep 接收输入,我不确定如何在 xargs 的上下文中设置 $1。
答案1
按照您尝试的方式:
grep bar my_shell_script.sh | bash -- /dev/stdin some_value
注意,在上面的代码中,new 的 stdinbash
来自grep
。如果 newbash
运行的命令也从 stdin 读取,那么该命令将从 读取grep
。为了安全起见,或者如果您明确想要将 stdin 用于其他用途,请使用以下语法:
bash <(grep bar my_shell_script.sh) my-bash some_value
# or
bash -c "$(grep bar my_shell_script.sh)" my-bash some_value
或者如果你想要在当前 shell 中执行代码:
. <(grep bar my_shell_script.sh) some_value
笔记:
- 您不想
$1
在您的文件中引用吗? - 进程替换 (
<(…)
) 不可移植。您标记了狂欢,Bash 支持它。命令替换 ( ) 是可移植的,但如果 的输出太长,$(…)
它将失败。argument list too long
grep
my-bash
解释如下:中的第二个 sh 是什么sh -c 'some shell code' sh
?(解释是在sh -c
/的上下文中bash -c
)。/dev/stdin
可能存在于您的操作系统中,也可能不存在。- 这个答案没有讨论通过使用 过滤“脚本”来运行代码的合理性
grep
。在这件事上,我假设你知道你想要什么。