Вопрос или проблема
Вот что я пытаюсь сделать (в скрипте):
#!/usr/bin/env bash
if [[ ! $("/usr/bin/scp [email protected]:/Users/seamus/Downloads/imgutils/image-utils* /home/pi/testscp") ]]; then
printf "\nОШИБКА И ВЫХОД: 'scp' не удалось \n"
exit 1
fi
printf "успех!\n"
Я пробовал сделать это различными способами, но ничего не срабатывает. Вот что я получаю из вышеуказанного:
./testscp.sh: line 3: /usr/bin/scp [email protected]:/Users/seamus/Downloads/imgutils/image-utils* /home/pi/testscp: Нет такого файла или каталога
ОШИБКА И ВЫХОД: 'scp' не удалось
Команда scp
выполняется нормально, когда она находится на отдельной строке. Если я делаю это, я могу протестировать $0
– что работает нормально… но я предпочел бы сделать это все в одной строке. Что я упускаю?
Используйте if
отдельно и заключите аргумент, содержащий глобус, предназначенный для scp
, в кавычки:
if ! /usr/bin/scp '[email protected]:/Users/seamus/Downloads/imgutils/image-utils*' /home/pi/testscp; then
printf>&2 "\nОШИБКА И ВЫХОД: 'scp' не удалось \n"
exit 1
fi
printf "успех!\n"
В bash кавычки используются для разделения ОДНОГО ярлыка, который в противном случае будет интерпретирован как несколько ярлыков (из-за пробелов). Поэтому, когда bash читает:
if [[ ! $("/usr/bin/scp [email protected]:/Users/seamus/Downloads/imgutils/image-utils* /home/pi/testscp") ]]
Он интерпретирует это как:
if [[ ! $( ДЛИННОЕ_ИМЯ_ИСПОЛНЯЕМОГО_ФАЙЛА_С_СТРАННЫМИ_СИМВОЛАМИ ) ]]; then
Ваши кавычки не на том месте.
Чтобы разложить это на исполняемое, есть несколько способов это записать, но просто:
if [[ ! $(/usr/bin/scp [email protected]:/Users/seamus/Downloads/imgutils/image-utils* /home/pi/testscp) ]]; then
достаточно.
Но, как говорит @StephenKitt, сочетание теста ([[...]]
) и экспансии ($(...)
) является избыточным. Действительно (как указывает ikkachu ниже), это тестирует на ненулевой ответ на stdout, А НЕ код завершения scp.
но я предпочел бы сделать это все в одной строке.
Это вопрос стиля, а не функциональности, но я предполагаю, что писать скрипты с очень длинными строками – это не хороший стиль.
Ответ или решение
Когда речь идет о выполнении команд в Bash, особенно таких, как scp
, важно учитывать правильное использование синтаксиса для проверки успешности выполнения. В вашем случае ошибка заключается в том, что вы неверно разместили кавычки и использовали конструкции, которые не соответствуют логике проверки.
Проблема с вашим кодом
Ваш первоначальный код:
if [[ ! $("/usr/bin/scp [email protected]:/Users/seamus/Downloads/imgutils/image-utils* /home/pi/testscp") ]]; then
printf "\nERROR & EXIT: 'scp' failed \n"
exit 1
fi
printf "success!\n"
-
Неверное использование $(): Конструкция
$()
используется для подстановки результата команды в другое выражение. В вашем случае вы пытаетесь проверить успешность выполнения командыscp
, но делаете это неправильно. Вместо этого вам нужно просто использовать команду внутри условия. -
Неверные кавычки: Правильное использование кавычек позволяет Bash корректно интерпретировать аргументы команды. Ваша команда
scp
использует глагольные конструкции, где кавычки необходимы для определения одного аргумента.
Правильный подход
Чтобы исправить ваш скрипт, используйте следующую структуру:
#!/usr/bin/env bash
if ! /usr/bin/scp '[email protected]:/Users/seamus/Downloads/imgutils/image-utils*' /home/pi/testscp; then
printf >&2 "\nERROR & EXIT: 'scp' failed \n"
exit 1
fi
printf "success!\n"
Объяснение изменений
-
Убрали
$()
: Условие теперь проверяет успешность выполнения командыscp
напрямую. Bash проверяет код возврата команды, а не значение, возвращаемое командой. -
Использование одинарных кавычек: Кавычки гарантируют, что Bash интерпретирует путь с символами
*
как шаблон для поиска файлов, а не как часть строки. -
Исправление перенаправления вывода: Использование
>&2
перенаправляет сообщение ошибки на стандартный поток ошибок, что является хорошей практикой.
Заключение
Ваш первоначальный подход к использованию условий делает ваш скрипт неэффективным и приводит к ошибкам. Рассмотрите предложенные изменения, чтобы улучшить читаемость, производительность и надежность вашего кода. При написании скриптов в Bash важно следовать ясной и логичной структуре, что облегчит отладку и поддержку вашего кода в будущем.