2016-01-06 7 views
1

в C-оболочке Мне нужно проверить, существует ли файл или старше его (или в этом примере старше 5 секунд с начала unix время). если файл не существует или старый, некоторые вещи должны быть выполнены.проверьте, нет ли файла или старше другого в csh

В моем примере «bla.txt» не существует, так что первое условие истинно

if (! -f bla.txt || `stat -c "%Y" bla.txt` > 5) echo 1 
stat: cannot stat `bla.txt': No such file or directory 
1 

Проблема, если я совмещаю эти условия, если заявление, второй (возраст файла) выполняется, хотя первая из них уже истинна и дает ошибку, потому что файла там нет.

в Баш, все работает как надо

if [ ! -f bla.txt ] || [ `stat -c "%Y" bla.txt` > 5 ]; then echo 1; fi 
1 

любые идеи о том, как добиться такого поведения в CSH без else if? Я не хочу, чтобы команды выполнялись дважды в моем коде.

спасибо!

+0

Я просто понял, как неправильно второе условие, если заявление для команды Баша, но он не выполняется, так что это не имеет значения ^^ – muluman88

ответ

1

У CSH есть синтаксический анализатор, который, честно говоря, не заслуживает названия.

Проблема в данном конкретном случае заключается в том, что она не оценивает левую часть слова || сначала создайте перед началом stat (как вы видели). Поскольку вы зависите от стандартного вывода stat, вы не можете перенаправить вывод через >& /dev/null, и перенаправление только stderr немного неприятно (см. Redirecting stderr in csh).

Если вы хотите, чтобы чистый код csh, который по-прежнему понятен, но не хочет дважды кодировать фактический кодовый вызов, я считаю, что самым чистым решением является использование промежуточной переменной. Что-то вроде этого:

#!/bin/csh 
set f=$1 
set do=0 
if (! -f $f) then 
    set do=1 
else 
    if (`stat -c "%Y" $f >& /dev/null ` < 5) set do=1 
endif 

if ($do) echo "File $f does not exist or is older than 5s after epoch" 

(. Обратите внимание, что исходный код также был тест возраста обращенного из вашей прозы)

+0

спасибо! это действительно чистое решение. извините за испорченный пример. – muluman88

0

Вы можете переместить тест -f внутри команды оболочки, из которой вы перенаправляете вывод stat. Вот сценарий для иллюстрации:

#!/bin/csh                 
set verbose 
set XX=/tmp/foo 
set YY=2 
rm -f $XX 
foreach ZZ (0 1) 
    if (` stat -c "%Y" $XX` > $YY) echo 1 
    if (` test -f $XX && stat -c "%Y" $XX` > $YY) echo 1 
    if ($ZZ == 0) touch $XX 
    stat -c "%Y" $XX 
    sleep $YY 
end 
+0

Это не выполняет желаемую команду (второй эхо 1 в коде), когда файл не существует. – fork2execve

+0

Собственно, вопрос * вопроса * как таковой был, как устранить сообщение об ошибке. Если бы я переписал сценарий OP, я мог бы сделать это по-другому (и все еще в одной строке, как запросил OP). –