MUTE='&> /dev/null'
echo "text" $MUTE
有没有办法让重定向保持在变量内部?
答案1
在我看来,使用变量的存在/值来有条件地关闭文件描述符会更优雅,例如
$ cat myscript.sh
#!/bin/bash
if [ -n "$MUTE" ]; then
exec &>-
fi
echo somestuff
echo someerr >&2
然后
$ ./myscript.sh
somestuff
someerr
但
$ MUTE=yes ./myscript.sh
$
如果你真的想切换重定向,您可以考虑创建一个 shell 函数,在关闭文件描述符之前复制它们,然后恢复重复项以重新启用原始流,例如
#!/bin/bash
function mute {
case "$1" in
"on")
exec 3>&1-
exec 4>&2-
;;
"off")
exec 1>&3-
exec 2>&4-
;;
*)
esac
}
# Demonstration:
echo "with mute on: "
mute on
ls somefile
ls nofile
mute off
echo "with mute off: "
ls somefile
ls nofile
结果:
$ ./mute.sh
with mute on:
with mute off:
somefile
ls: cannot access nofile: No such file or directory
答案2
- 解析器标记为变量赋值(命令名前面的词)和重定向的词被保存以供稍后处理。
- 那些不是变量赋值或重定向的词会被扩展(参见 Shell 扩展)。如果扩展后还有剩余的词,则第一个词将被视为命令的名称,其余的词将被视为参数。
- 重定向按上述方式执行(参见重定向)。
这意味着命令解析器首先识别所有重定向,然后执行各种扩展,最后解析它先前识别的重定向:这些不包括扩展可能导致的重定向。
但是来自help eval
:
Execute arguments as a shell command.
Combine ARGs into a single string, use the result as input to the shell,
and execute the resulting commands.
因此,eval
你可以创建一种间接级别,允许命令被处理两次:
MUTE='&> /dev/null'
eval echo "text" $MUTE
$ MUTE='&> file'
$ eval echo "text" $MUTE
$ cat file
text
答案3
您可以使用一个函数将其写入stdin
您想要的任何位置。
$> MUTE(){ cat /dev/stdin > testFile.txt ; }
$> df | MUTE
$> cat testFile.txt
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1954208 4 1954204 1% /dev
tmpfs 393160 3548 389612 1% /run
/dev/sda1 115247656 95511252 13859056 88% /
none 4 0 4 0% /sys/fs/cgroup
none 5120 0 5120 0% /run/lock
none 1965792 872 1964920 1% /run/shm
none 102400 128 102272 1% /run/user
cgmfs 100 0 100 0% /run/cgmanager/fs
或者我们可以告诉函数通过重定向执行我们想要的任何操作
$> MUTE(){ "$@" > testFile.txt ; }
$> MUTE lsblk
$> cat testFile.txt
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 111.8G 0 disk
└─sda1 8:1 0 111.8G 0 part /
非标准方式,黑客手段,但它确实有效:)
答案4
它是这样工作的,我不知道它是否适用于你的方法:
MUTE='&> /dev/null'
bash -c "echo \"text\" $MUTE"