dro*_*oso 5 shell bash pipe io-redirection dash
脚本:
#!/bin/sh
#
# reads stdin/file and copies it to clipboard
# clears it after 30s
#
cat "${1:-/dev/stdin}" | timeout 30 xclip -i -selection clipboard -r -verbose &>/dev/null &
Run Code Online (Sandbox Code Playgroud)
我可以看到只有标准输入不起作用(使用 bash 它适用于标准输入/文件)。
PS verbose 用于使 xclip 不被守护进程。
dash
定位为 POSIX 标准。POSIX 仅指定[n]>
重定向。但bash
介绍了许多自己的特点。&>
是其中之一,表示输出描述符(stderr
和stdout
)。
您应该阅读有关bash 和 dash兼容性的文章。
也许您会得到有用的checkbashisms实用程序,它可以帮助bash
您在脚本中找到特定的指令。
[这个答案是关于脚本中的异步管道;对于已弃用的&>
bash 运算符以及为什么您应该始终使用它>output 2>&1
,请参阅过时和已弃用的语法]
Run Code Online (Sandbox Code Playgroud)#! /bin/sh cat "${1:-/dev/stdin}" | ... &
在这里,您有一个异步运行的管道(因为由 终止&
),从脚本启动,即来自禁用了作业控制的外壳程序。
根据标准:
command1 & [command2 & ... ]
在执行任何显式重定向之前,异步列表的标准输入应被视为分配给与
/dev/null
.
问题是dash
,ksh
,mksh
,yash
,等等解读为此“异步列表”为任何命令,包括一个管道,并重定向所述第一命令从标准输入/dev/null
:
$ echo foo | dash -c 'cat | tr fo FO & echo DONE'
DONE
$ echo | dash -c 'readlink /proc/self/fd/0 | cat & echo DONE'
DONE
/dev/null
Run Code Online (Sandbox Code Playgroud)
但bash
只会将其解释为“简单命令”,并且只会/dev/null
在它不属于管道时重定向其标准输入:
$ echo foo | bash -c 'cat | tr fo FO & echo DONE'
DONE
FOO
$ echo | bash -c 'readlink /proc/self/fd/0 | cat & echo DONE'
DONE
pipe:[69872]
$ echo | bash -c 'readlink /proc/self/fd/0 & echo DONE'
DONE
/dev/null
$ bash -c 'cat | tr a A & echo DONE'
DONE
cat: -: Input/output error
Run Code Online (Sandbox Code Playgroud)
zsh
只会/dev/null
在原始标准输入是 tty 时重定向它,而不是当它是其他类型的文件时:
$ zsh -c 'readlink /proc/self/fd/0 &' </dev/tty
/dev/null
$ zsh -c 'readlink /proc/self/fd/0 &' </dev/zero
/dev/zero
Run Code Online (Sandbox Code Playgroud)
适用于所有 shell 的解决方法是将 stdin 复制到另一个文件描述符中,并从中重定向第一个命令的 stdin:
#! /bin/sh
exec 3<"${1:-/dev/stdin}"
cat <&3 | timeout 30 xclip -i -selection clipboard -verbose -r >/dev/null 2>&1 &
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2331 次 |
最近记录: |