创建“2>/dev/null &”的缩写

创建“2>/dev/null &”的缩写

我正在尝试为自己编写一个 bash 脚本,其目的是在终端中普遍使用它。它应该启动一个应用程序作为后台进程并丢弃它的 stderr 输出。这是我得到的:

 for app in $@; do 
    $app 2>/dev/null
 done

它似乎可以在没有参数的情况下启动裸应用程序,script.sh firefox gedit但无法执行以下操作:

script.sh "vlc video.mp4"

我的问题是:如何增强这个基本脚本来处理以参数/文件作为输入的应用程序?也许已经有我可以使用的工具了?

答案1

有两个问题:

  1. 使用$@不带引号的。

    这将使循环将vlcvideo.mp4作为两个单独的项目进行迭代,即使它们位于脚本调用中的同一个带引号的字符串内。

  2. 在变量中使用命令。

    如果命令比单个简单命令更复杂,那么这将不起作用。您必须改为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
}

注意:这将只允许您一次运行一个命令。我不确定您的初衷是否是一次向脚本传递多个命令,如果是,我将删除。

相关内容