Ваш скрипт не делает то, что вы хотите, потому чтокогда timeout -t 10 command
имеет статус выхода 0 --, который является статусом выхода, который считается истинным в сценариях оболочки --, команда timeout -t 10 command || [ $? = 143 ]
просто завершается со статусом выхода 0 и не вызывает право -сторона ||
для запуска. Точно так же, если вы замените ||
на &&
, то любой ненулевой статус выхода из левой -стороны будет статусом выхода всей команды, а правая -сторона будет не быть запущенным.
Вы должны просто запустить их как две отдельные команды , разделив их ;
или новой строкой. При необходимости вы все равно можете использовать их оба в качестве условия if
, когда делаете это (, см. ниже ).
Я предполагаю, что вам нужен статус выхода timeout -t 10 command
, а не command
(, если он отличается от ). Иначе мне непонятно, чего вы хотите; , как и ilkkachu , я не знаком с командой timeout
, которая принимает параметр -t
. Обычно я бы предложил вам сделать это таким образом, за исключением того, что это звучит так, как будто ваше «внешнее ограничение» может запретить это, поскольку оно вообще не использует if
:
timeout -t 10 command
test "$?" -eq 143
exit
Команда test
/ [
возвращает код выхода 0, чтобы указать true, и 1, чтобы указать false, поэтому вам не нужно писать отдельные ветки с exit 0
и exit 1
. Встроенная команда exit
при запуске без аргументов заставляет оболочку возвращать статус выхода последней выполненной команды.
Если вы уже находитесь в конце скрипта, то вы можете опустить exit
, потому что когда управление перетекает из конца скрипта, это имеет тот же эффект, что иexit
:
timeout -t 10 command
test "$?" -eq 143
(В любом случае вы можете написать [ "$?" -eq 143 ]
вместо test "$?" -eq 143
, если хотите. Подробнее об использовании [
/ test
см. ниже.)
Хотя ваше описание звучит так, будто вы не можете использовать этот код в точности, вы, тем не менее, должны быть в состоянии изменить его, чтобы он принял требуемую форму.Вы сказали, что должны не только выполнить проверку , но также запустить команду в предложении if
. Это, по-видимому, запрещает удобочитаемый и идиоматический подход, предложенный Хауке Лагингом запуска команды перед if
.
Так что, если вы не можете этого сделать, вы можете включить команду в условие if
, как вы это делали, но отделить ее от вашей команды test
/ [
с помощью ;
, а не||
:
if timeout -t 10 command; [ "$?" -eq 143 ]; then
exit 0
else
exit 1
fi
(Вы можете обойтись без"
"
вокруг $?
. Вы также можете написать =
вместо 143
, хотя это сбивает с толку, потому что =
означает текстовое, а не числовое сравнение. Вы можете написать test "$?" -eq 143
вместо [ "$?" -eq 143 ]
, если хотите.)
Причина, по которой это работает, заключается в том, что вам разрешено писать if
условие, состоящее из нескольких команд, разделенных точкой с запятой или даже новой строкой. Вот почему грамматика оболочки требует, чтобы вы писали then
, чтобы указать конец условия if
. Поэтому вам не нужно пытаться обходным путем использовать оператор &&
или ||
, когда ваша цель состоит в том, чтобы запустить две команды в качестве условия if
, заставляя if
самостоятельно проверять только вторую.
Обратите внимание, что я предлагаю это только потому, что вы сказали, что все должно быть в состоянии if
. Я не рекомендую писать такие сценарии, когда в этом нет необходимости.
Чтобы вывести все строки файла до совпадения определенного шаблона (и чтобы не выводить эту совпадающую строку ), вы можете использовать
sed -n '/PATTERN/q; p;' file
Здесь вывод пространства шаблонов по умолчанию в конце каждого цикла отключен с помощью -n
. Вместо этого мы явно выводим каждую строку с p
. Если данный шаблон совпадает, мы останавливаем обработку с помощью q
.
Ваша фактическая, более длинная команда, которая изменяет имя хромосомы 21 с простого 21
на chr21
в первой строке файла fasta, а затем продолжает извлекать ДНК для этой хромосомы, пока не дойдет до следующей. строка заголовка fasta, может быть записана как
sed -n -e '1 { s/^>21/>chr21/p; d; }' \
-e '/^>/q' \
-e p <in.fasta >out.fasta
или
sed -n '1 { s/^>21/>chr21/p; d; }; /^>/q; p' <in.fasta >out.fasta
Проблема с вашим исходным выражением заключается в том, что d
запускает новый цикл (, т. е. принудительно считывает следующую строку в пространство шаблонов, и происходит переход к началу скрипта ). Это означает, что q
никогда не будет выполнен.
Обратите внимание, что для синтаксической корректности в системах, отличных от -GNU, исходный сценарий должен выглядеть как /PATTERN/ { d; q; }
. Обратите внимание на добавленный ;
послеq
(пробелы не имеют значения ).
Вы можете получить тот же вывод (, только те строки, которые предшествуют первому совпадению ), используя две формы адреса -:
sed -e '/PATTERN/,$d'
Но в отличие от методов, использующих q
, это означает, что sed
продолжает чтение каждой входной строки. Это может иметь значение для больших входных файлов или при чтении из конвейера.