Ich behalte einen Prozess in FreeBSD mithilfe eines Skripts im Auge, das den aktuellen Status des Jobs ausgibt.
Mithilfe des csh
integrierten Befehls repeat
möchte ich das Skript alle 2 Sekunden ausführen. Daher würde ich naiverweise gerne so etwas tun:
repeat 100000 ./dumpstatus ; sleep 2
Offensichtlich funktioniert das Semikolon nicht wie vorgesehen, aber ich kann nicht die richtige Syntax finden, um es einzubinden.
Ich kann das Problem umgehen, indem ich eine neue Shell-Instanz unter folgendem Namen aufrufe repeat
:
repeat 100000 sh -c 'path/to/script/dumpstatus ; sleep 2'
aber das ist alles andere als ideal und nimmt pwd
auch keinen Weg vom Strom, was ärgerlich ist :)
Ich habe es auch repeat 10000 ( ./dumpstatus ; sleep 2)
mit und ohne Escapen der Klammern versucht, das funktioniert auch nicht und ich bin mir nicht ganz sicher, warum.
Wie kann ich dies richtig tun, ohne aufzurufen sh -c
, sodass das Semikolon wie gewünscht interpretiert wird?
Antwort1
Ich glaube, dass dies ohne den Aufruf einer Shell nicht möglich ist, da die CSH-Manpage (unter anderem) besagt:
wiederholenZählbefehl
Der angegebene Befehl, der denselben Einschränkungen unterliegt wie der Befehl in der einzeiligen if-Anweisung oben, wird count-mal ausgeführt. …
kombiniert mit der if
Beschreibung:
Wenn (Ausdruck)Befehl
... Der Befehl muss ein einfacher Befehl sein, kein Alias, keine Pipeline, keine Befehlsliste und keine in Klammern gesetzte Befehlsliste, aber er kann Argumente haben.
... scheint mir andere Optionen auszuschließen.
Ich kann Ihren $PWD-Fehler im Beispiel nicht reproduzieren sh -c
. Angesichts dieses Skripts in meinem Home-Verzeichnis:
$ cat ~/script.sh
#!/bin/sh
echo $0 pwd is $PWD
Und ein Beispiellauf von:
$ csh
$ echo $version
tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-unknown-linux) options wide,nls,dl,al,kan,rh,color,filec
$ cd /tmp
$ repeat 2 sh -c '~/script.sh; sleep 2'
/home/me/script.sh pwd is /tmp
/home/me/script.sh pwd is /tmp
... zeigt die Ausführung von script.sh vom $PWD der übergeordneten Shell.
Antwort2
Da repeat
eine Befehlsliste nicht analysiert werden kann, ist dies nicht möglich. Ich wünschte, man csh man
könnte es so klar und deutlich sagen:
repeat count command
The specified command must be a simple command, (not a pipeline, not a
command list, nor a parenthesized command list), and is executed count
times. I/O redirections occur exactly once, even if count is 0.
Beachten Sie die Beschränkung auf eine einzelne Umleitung, die die Verwendung einer while
Schleifenumgehung unpraktisch macht. Beispiel, das keine 9 Leben ausgibt:
echo lives | repeat 9 cat | wc -l
1
Quelle: das eigentliche Zitat von man csh
(aber lesen Sie repeat
zuerst den Eintrag zu und dann den if
Eintrag) ist etwas umständlich:
COLUMNS=90 man csh | egrep -A 7 ' (repeat|if).*and$' | sed -n '1,13{s/^ \{10\}//p}'
if (expr) command
If the specified expression evaluates to true, then the single
command with arguments is executed. Variable substitution on
command happens early, at the same time it does for the rest of the
if command. command must be a simple command, not a pipeline, a
command list, or a parenthesized command list. Input/output redi‐
rection occurs even if expr is false, i.e., when command is not exe‐
cuted (this is a bug).
repeat count command
The specified command, which is subject to the same restrictions as
the command in the one line if statement above, is executed count
times. I/O redirections occur exactly once, even if count is 0.