我想运行一个bash脚本,并能够看到用于启动它的命令行:
sh myscript.sh arg1 arg2 1> output 2> error
以便了解用户是否使用了" 标准重定向" &#39 1为卤素;'和' 2>',因此调整我的脚本的输出。
是否可以使用内置变量?
感谢。
答案 0 :(得分:2)
不太可能。您可以检查stdout
和stderr
是否指向终端:[ -t 1 -a -t 2 ]
。但如果他们这样做,并不一定意味着他们没有重定向(想想>/dev/tty5
)。如果他们不这样做,则无法区分stdout
和stderr
被关闭以及被重定向。即使你确定 被重定向,你也无法从脚本本身告诉他们在重定向后指向的位置。
答案 1 :(得分:2)
在Linux和一些类似unix的系统上,/proc/self/fd/1
和/proc/self/fd/2
是 std重定向所指向的符号链接。使用readlink
,我们可以通过将它们与父进程进行比较来查询它们是否被重定向。文件描述符。
但我们不会使用self
而是使用$$
,因为$(readlink /proc/"$$"/fd/1)
会生成一个新的shell,因此self不再引用当前的bash脚本而是引用子shell。
$ cat test.sh
#!/usr/bin/env bash
#errRedirected=false
#outRedirected=false
parentStderr=$(readlink /proc/"$PPID"/fd/2)
currentStderr=$(readlink /proc/"$$"/fd/2)
parentStdout=$(readlink /proc/"$PPID"/fd/1)
currentStdout=$(readlink /proc/"$$"/fd/1)
[[ "$parentStderr" == "$currentStderr" ]] || errRedirected=true
[[ "$parentStdout" == "$currentStdout" ]] || outRedirected=true
echo "$0 ${outRedirected:+>$currentStdout }${errRedirected:+2>$currentStderr }$@"
$ ./test.sh
./test.sh
$ ./test.sh 2>/dev/null
./test.sh 2>/dev/null
$ ./test.sh arg1 2>/dev/null # You will lose the argument order!
./test.sh 2>/dev/null arg1
$ ./test.sh arg1 2>/dev/null >file ; cat file
./test.sh >/home/camusensei/file 2>/dev/null arg1
$
不要忘记用户还可以重定向到 3rd 文件描述符,该描述符在其他内容上打开...!