Я слежу за процессом во FreeBSD с помощью скрипта, который выводит текущий статус задания.
Используя csh
встроенную команду repeat
, я хотел бы запускать скрипт каждые 2 секунды, поэтому наивно хотел бы сделать что-то вроде этого:
repeat 100000 ./dumpstatus ; sleep 2
Очевидно, что точка с запятой не будет работать так, как задумано, но я не могу найти правильный синтаксис для ее включения.
Я могу обойти эту проблему, вызвав новый экземпляр оболочки в repeat
:
repeat 100000 sh -c 'path/to/script/dumpstatus ; sleep 2'
но это вряд ли идеально, и к тому же не отклоняется от течения, pwd
что раздражает :)
Я также пробовал repeat 10000 ( ./dumpstatus ; sleep 2)
с экранированием скобок и без него, это тоже не работает, и я не совсем понимаю, почему.
Как правильно это сделать, не вызывая sh -c
, чтобы точка с запятой была интерпретирована так, как мне бы хотелось?
решение1
Я считаю, что это невозможно без вызова оболочки, как указано в man-странице csh (частично):
повторитькоманда подсчета
Указанная команда, на которую распространяются те же ограничения, что и команда в однострочном операторе if выше, выполняется указанное количество раз. ...
в сочетании с if
описанием:
если (выражение)команда
... команда должна быть простой командой, а не псевдонимом, конвейером, списком команд или списком команд в скобках, но она может иметь аргументы.
... как мне кажется, исключает другие варианты.
Я не могу воспроизвести ваш сбой $PWD в sh -c
примере. При наличии этого скрипта в моем домашнем каталоге:
$ cat ~/script.sh
#!/bin/sh
echo $0 pwd is $PWD
И пример запуска:
$ 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
... показывает выполнение script.sh из $PWD родительской оболочки.
решение2
Поскольку repeat
невозможно разобрать список команд, это невозможно сделать. Хотелось бы, чтобы это csh man
можно было выразить так:
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.
Обратите внимание на ограничение на одно перенаправление, что делает использование while
обходного пути цикла непрактичным. Пример, который не выводит 9 жизней:
echo lives | repeat 9 cat | wc -l
1
Источник: фактическая цитата man csh
(но сначала прочтите запись repeat
, а затем if
запись), немного окольна:
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.