Skript:
#!/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 &
Ich sehe, dass nur stdin nicht funktioniert (mit bash funktioniert es mit stdin/file).
PS: Verbose wird verwendet, damit xclip nicht als Daemon ausgeführt wird.
Antwort1
&>
ist ein Bashismus, Sie müssen es >/dev/null 2>&1
für POSIX-Shells ändern in
Antwort2
[Diese Antwort bezieht sich auf asynchrone Pipelines in Skripten. Informationen zum veralteten &>
Bash-Operator und warum Sie ihn >output 2>&1
stattdessen immer verwenden sollten, finden Sie unterveraltete und nicht mehr empfohlene Syntax]
#! /bin/sh cat "${1:-/dev/stdin}" | ... &
Hier haben Sie eine Pipeline, die asynchron ausgeführt wird (weil sie durch beendet wurde &
), und die von einem Skript gestartet wird, d. h. von einer Shell mit deaktivierter Jobsteuerung.
Entsprechend derStandard:
command1 & [command2 & ... ]
Die Standardeingabe für eine asynchrone Liste gilt, bevor explizite Umleitungen durchgeführt werden, als einer Datei zugewiesen, die dieselben Eigenschaften wie hat
/dev/null
.
Das Problem besteht darin, dass dash
, ksh
, mksh
, yash
, usw. „asynchrone Liste“ als jeden beliebigen Befehl, einschließlich einer Pipeline, interpretieren und die Standardeingabe des ersten Befehls von folgendem umleiten /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
Aber bash
es wird nur als "einfacher Befehl" interpretiert und wird nur dann seine Standardeingabe umleiten, /dev/null
wenn esnichtTeil einer Pipeline:
$ 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
zsh
leitet es nur um /dev/null
, wenn die ursprüngliche Standardeingabe ein TTY ist, nicht, wenn es sich um einen anderen Dateityp handelt:
$ zsh -c 'readlink /proc/self/fd/0 &' </dev/tty
/dev/null
$ zsh -c 'readlink /proc/self/fd/0 &' </dev/zero
/dev/zero
Ein Workaround, der in allen Shells funktioniert, besteht darin, die Standardeingabe in einen anderen Dateideskriptor zu duplizieren und die Standardeingabe des ersten Befehls von dort umzuleiten:
#! /bin/sh
exec 3<"${1:-/dev/stdin}"
cat <&3 | timeout 30 xclip -i -selection clipboard -verbose -r >/dev/null 2>&1 &
Antwort3
dash
als POSIX-Standard positioniert. POSIX spezifiziert nur [n]>
die Umleitung. bash
Führt aber viele eigene Features ein. &>
ist eines davon und bedeutet Ausgabedeskriptoren ( stderr
und stdout
).
Sie sollten den Artikel lesen überBash und DashKompatibilität.
Vielleicht bekommst du hilfreichCheckbashismenbash
Dienstprogramm, das beim Auffinden spezifischer Anweisungen in Ihren Skripten helfen kann .