Тест или [или [[более портативен и между оболочками удара и между другими оболочками?

Таким образом, то, что Вы имеете и хотите сделать в основном, сводится к следующему.

command1 &
wait 
sleep 

command2 &
wait 
sleep 

...

В этом случае, удаляя фоновую обработку (&) а также wait и sleep заставит команды выполняться в последовательности. Это, однако, заставит их сразу выполниться друг после друга.

Для ожидания до определенного времени Вы можете sleep для соответствующего количества времени. sleep занимает много секунд в качестве входа, и системы Unix традиционно сохраняют и измеряют время в секундах, таким образом, это сводится к простой арифметике:

  1. Преобразуйте ожидание - для даты и времени к секундам с эпохи.
  2. Преобразуйте текущее время в секунды с эпохи.
  3. Вычислите различие.
  4. Сон для этого долго.

Как сделать, который приятно размечается в этом ответе Переполнения стека, но скопировать основную часть:

current_epoch=$(date +%s)
target_epoch=$(date -d '01/01/2010 12:00' +%s)
sleep_seconds=$(( $target_epoch - $current_epoch ))
sleep $sleep_seconds

Тем конкретным примером является синтаксис удара, но должно быть довольно легко преобразовать в примерно любой язык сценариев оболочки. $(...) выполняет команду и замены выводом той команды, и $(( ... )) оценивает арифметическое выражение.

GNU date -d также поддерживает метки времени только для времени, таким образом, можно сказать date -d '05:00' и это переведет это в ближайшее 5:00.

Соединяя это, должно быть легко сделать сценарий как тот, который Вы хотите.

44
19.11.2014, 15:33
7 ответов

[ [ - это синоним тестирования команда , и она одновременно работает Bash встроенный и отдельная команда. Но [[ - это ключевое слово Bash и работает только в некоторых версиях. Таким образом, по соображениям портативности вам лучше использовать один тест [] или

[ -w "/home/durrantm" ] && echo "writable"
31
27.01.2020, 19:34

Да, есть различия. Наиболее переносными являются тест или [] [] . Это как часть POSIX теста спецификация .

, если ... Fi Construct также , определенный POSIX и должен быть полностью портативным.

[ [[[]] [ [[[]] [113449] [[[]] - это функция ksh , которая также присутствует в некоторых версиях Bash ( всех современных ) , в ZSH и, возможно, в других, но нет в SH или или или различные другие более простые оболочки.

Итак, чтобы сделать ваши сценарии портативными, использовать [] , , , или , если ... Fi .

-121--9848-

Для портативности, используйте тест / [. Но если вам не нужна переносимость, ради здравомыслия себя и других читает ваш сценарий [[. :)

Также см. , в чем разница между тестом, [и [[? в Bashfaq .

7
27.01.2020, 19:34

Да, существуют различия. Самые портативные тест или [] . Это оба часть тест POSIX спецификация .

, если... конструкция fi также определена POSIX и должна быть абсолютно портативной.

[[]] функция ksh , которая также присутствует в некоторых версиях удар ( все современные ), в zsh и возможно в других, но не присутствует в sh или тире или различные другие более простые оболочки.

Так, для создания сценариев портативными, использование [] , тест или , если... fi.

35
27.01.2020, 19:34

Отметьте, тот [] , && cmd не является тем же как если. конструкция fi .

Иногда его поведение его довольно подобное и вы можете использовать [] && cmd вместо если. fi. Но только иногда. Если у вас есть более затем одна команда, чтобы выполниться, если для условия или вас нужно если. еще. fi быть осторожным и смотреть на логику.

Несколько примеров:

[ -z "$VAR" ] && ls file || echo wiiii

Не то же как

if [ -z $VAR ] ; then
  ls file
else
  echo wiii
fi

, потому что, если ls перестанет работать, , эхо будет выполняться, которого не произойдет с если .

Другой пример:

[ -z "$VAR" ] && ls file && echo wiii

не то же как

if [ -z "$VAR" ] ; then
   ls file
   echo $wiii
fi

, хотя эта конструкция будет действовать тот же

[ -z "$VAR" ] && { ls file ; echo wiii ; }

примечание ; после того, как эхо важно и должно быть там.

Настолько возобновляющийся оператор выше мы можем сказать

[] && cmd ==, если первая команда успешна, затем выполняют следующий

если. fi ==, если условие (который может быть тестовой командой также) затем выполняет команду (команды)

Так для мобильности между [ и [[ использование [ только.

, если совместимый POSIX. Таким образом, если необходимо выбрать между [ и , если выбирают рассмотрение задачи и ожидаемого поведения.

20
27.01.2020, 19:34

Если вам нужна портативность за пределами мира, похожего на Борн, то:

test -w /home/durrantm && echo writable

- самая портативная. Она работает в ракушках семейства Борн, csh и rc.

test -w /home/durrantm && echo "writable"

выводит "записываемый" вместо записываемый в оболочках семейства rc (rc, es, akanga, где " не является особенным).

[ -w /home/durrantm ] && echo writable

не будет работать в оболочках семейств csh или rc на системах, которые не имеют команды [ в $PATH (некоторые из них, как известно, имеют test, но не его [] псевдоним).

if [ -w /home/durrantm ]; then echo writabe; fi

работает только в ракушках семейства Борн.

[[ -w /home/durrantm ]] && echo writable

работает только в ksh (где он возник), zsh и bash (все 3 в семействе Борнов).

Никто не будет работать в рыбном панцире там, где вам нужно:

[ -w /home/durrantm ]; and echo writable

или:

if [ -w /home/durrantm ]; echo writable; end
7
27.01.2020, 19:34

Моя самая важная причина выбора либо if foo; then bar; fi или foo && bar заключается в том, важен ли статус выхода всей команды.

сравните:

#!/bin/sh
set -e
foo && bar
do_baz

с:

#!/bin/sh
set -e
if foo; then bar; fi
do_baz

Вы можете подумать, что они делают то же самое; однако, если foo не срабатывает (или является ложным, в зависимости от вашей точки зрения), то в первом примере команда do_baz не будет выполнена, так как скрипт завершил работу.... Набор -e предписывает оболочке немедленно выйти, если какая-либо команда вернет ложное состояние. Очень полезно, если вы делаете такие вещи, как:

cd /some/directory
rm -rf *

Вы не хотите, чтобы скрипт продолжал выполняться, если cd по каким-либо причинам не работает.

0
27.01.2020, 19:34

На самом деле && заменяет if, а не test: оператор if в сценариях shell проверяет, вернула ли команда "успешный" (нулевой) статус выхода; в вашем примере это команда [.

Таким образом, вы варьируете две вещи: команду, используемую для запуска теста, и синтаксис, используемый для выполнения кода, основанного на результатах этого теста.

Команды теста:

  • test - это стандартизированная команда для оценки свойств строк и файлов; в вашем примере вы выполняете команду test -w /home/durrantm
  • [ - это псевдоним этой команды, столь же стандартизированный, который имеет обязательный последний аргумент ], чтобы выглядеть как выражение в скобках; не обманывайтесь, это все еще просто команда (вы даже можете обнаружить, что в вашей системе есть файл под названием /bin/[])
  • .
  • [[] - это расширенная версия команды test, встроенная в некоторые оболочки, но не являющаяся частью того же стандарта POSIX; она включает дополнительные опции, которые вы здесь не используете

Условные выражения:

  • Оператор && (стандартизирован здесь) выполняет логическую операцию AND, оценивая две команды и возвращая 0 (что означает true), если они обе возвращают 0; он будет оценивать вторую команду, только если первая вернула ноль, поэтому его можно использовать как простое условное выражение
  • Оператор if .... ... then ... fi (стандартизированная здесь) использует тот же метод оценки "истинности", но позволяет использовать составной список утверждений в пункте then, вместо единственной команды, предоставляемой замыканием &&, и обеспечивает elif и else клаузы, которые трудно написать, используя только && и ||. Обратите внимание, что в выражении if нет скобок вокруг условия.

Итак, все следующие варианты вашего примера одинаково переносимы и полностью эквивалентны:

  • test -w /home/durrantm && echo "writable"
  • [ -w /home/durrantm ] && echo "writable"
  • if test -w /home/durrantm; then echo "writable"; fi
  • if [ -w /home/durrantm ]; then echo "writable"; fi

Следующие также эквивалентны, но менее переносимы из-за нестандартной природы [[:

  • [[ -w /home/durrantm ]] && echo "writable"
  • if [[ -w /home/durrantm ]]; then echo "writable"; fi
9
27.01.2020, 19:34

Теги

Похожие вопросы