Это странно.
Я изменил ваш пример на что-то, что, как мне кажется, более ясно иллюстрирует проблему. (Обратите внимание, что $?
является псевдонимом для $status
.)
#!/bin/tcsh -f
foreach i (1 2 3)
false
# echo false status=$status
end
echo Done status=$status
Вывод будет
Done status=0
Если я раскомментирую команду echo
в цикле, выводэто:
false status=1
false status=1
false status=1
Done status=0
(Конечно, echo
в цикле все равно нарушит логику, потому что команда echo
завершается успешно и устанавливает $status
в ноль.)
Я думаю , что происходит, что end
, который завершает цикл, выполняется как оператор, и он устанавливает $status
($?
) на 0.
Я вижу то же самоеПоведение с tcsh
и bsd-csh
.
Сохранение значения $status
в другой переменной сразу после команды - хороший обходной путь - и, возможно, просто лучший способ сделать это, так как $status
очень хрупкий, и почти буквально будет засорен, если вы посмотрите на него.
Обратите внимание, что я добавил опцию -f
в строку #!
. Это не позволяет tcsh
получить исходные файлы инициализации (.cshrc
или .tcshrc
) и считается хорошей практикой. (Это не относится к sh / bash / ksh / zsh, которые присваивают совершенно другое значение -f
.)
Отступление: я регулярно использовал tcsh
в течение многих лет, оба в качестве интерактивного входа в системуоболочка и для скриптинга. Я бы не ожидал, что end
установит $status
. Это не первый раз, когда я должен был узнать, как tcsh
или csh
ведет себя методом проб и ошибок, и был удивлен результатом. Это одна из причин, по которой я переключился на bash
для интерактивного использования и использования сценариев. Я не скажу вам сделать то же самое, но вы можете прочитать классику Тома Кристиансена " csh.whynot ".