我正在尝试为自己编写一个 bash 脚本,其目的是在终端中普遍使用它。它应该启动一个应用程序作为后台进程并丢弃它的 stderr 输出。这是我得到的:
for app in $@; do
$app 2>/dev/null
done
它似乎可以在没有参数的情况下启动裸应用程序,script.sh firefox gedit
但无法执行以下操作:
script.sh "vlc video.mp4"
我的问题是:如何增强这个基本脚本来处理以参数/文件作为输入的应用程序?也许已经有我可以使用的工具了?
答案1
有两个问题:
使用
$@
不带引号的。这将使循环将
vlc
和video.mp4
作为两个单独的项目进行迭代,即使它们位于脚本调用中的同一个带引号的字符串内。在变量中使用命令。
如果命令比单个简单命令更复杂,那么这将不起作用。您必须改为
eval
给定的字符串。
考虑到这一点,您的脚本可能如下所示
#!/bin/sh
for cmd do # or: for cmd in "$@"; do
eval "$cmd" 2>/dev/null
done
称其为
./script 'echo "hello world"' 'vim "$HOME/.profile"' 'tr a-z A-Z <"$HOME/.profile" | grep -c EXPORT'
首先运行echo "hello world"
,完成后,它将打开vim
以编辑第二个命令中的指定文件。最后一个命令更复杂,但由我们使用的事实来处理(它只是将所有字母字符更改为大写并计算字符串在文件中出现的eval
次数)。EXPORT
一旦vim
会话退出,它就会运行。
有了这个,你甚至可以做
./script 'd=$HOME' 'ls "$d"'
即,设置在后面的命令中使用的变量。这是有效的,因为 调用的命令eval
是在与脚本相同的环境中运行的。如果您将命令作为后台任务启动,那么这将不起作用,正如您的问题标题所示。
答案2
您当前告诉脚本将每个参数作为单独的应用程序进行处理。所以你正在运行:
$ vlc
然后:
$ video.mp4
你应该让你的脚本更像这样:
#!/bin/bash
$@ 2>/dev/null
在我看来,哪个更适合作为函数:
func_name() {
$@ 2>/dev/null
}
注意:这将只允许您一次运行一个命令。我不确定您的初衷是否是一次向脚本传递多个命令,如果是,我将删除。