Выполнить сложные команды по сценарию bash

Я пытаюсь запустить следующую команду внутри сценария bash:

rm -rf `ls -t ${FOLDER}/other_folder | awk 'NR>5'` 

И я пытаюсь что-то вроде:

 RM_CMD="$(rm -rf 'ls -t ${FOLDER}/other_folder | awk NR>5')" 

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

Я пробовал несколько вариантов, но он всегда терпит неудачу, что здесь правильный подход?

-редактировать-

Дальнейшая информация

Если я попробую что-то вроде

 RM_CMD="rm -rf `ls -t ${FOLDER}/other_folder | awk 'NR>5'`" 

Кажется, что вы пытаетесь выполнить команду немедленно, чего я не намерен (я хочу сохранить правильную команду для последующего выполнения), но она получает все правильные значения, т. Е. Ничего пустого.

-edit 2-

Я попытался расщепить команды как можно больше, например:

 LS_CMD="ls -t ${FOLDER}/other_folder" AWK_CMD="awk 'NR>5' ${LS_CMD}" RM_CMD="rm -rf '${AWK_CMD}'" 

Но это дает эту проблему:

 + ssh -t user@server 'rm -rf '\''awk '\''NR>5'\'' ls -t /full/path/to/folder/other_folder'\''' bash: 5 ls -t /full/path/to/folder/other_folder: No such file or directory 

Обычно для таких вопросов ответ заключается в том, чтобы прочитать BashFAQ # 50: «Я пытаюсь поместить команду в переменную, но сложные случаи всегда терпят неудачу!» , Краткое описание: переменные предназначены для данных, а не для исполняемого кода, а попытки ввода кода в них имеют всевозможные проблемы.

Но в этом случае есть еще один важный фактор: вы будете запускать команду через ssh , а это значит, что она будет передана удаленной системе в виде данных и проанализирована как команда оболочки на удаленном компьютере. Это означает, что разумно хранить команду (как данные) в переменной в скрипте (на локальном компьютере).

Мне кажется, что самая большая проблема, с которой вы сталкиваетесь, заключается в том, что при использовании backquotes или $( ) (и они не в кавычках), команда внутри выполняется немедленно (на локальном компьютере) и ее вывод сохраняется в переменной. Чтобы избежать этого, вы можете избежать соответствующих символов при определении переменной:

 RM_CMD="rm -rf \$(ls -t '${FOLDER}/other_folder' | awk 'NR>5')" 

Обратите внимание: я использовал $( ) вместо backquotes, так как это обычно предпочтительнее. Мне кажется, что в некоторых случаях вы путаете обратные кавычки с одиночными кавычками; они выглядят похожими, но имеют совершенно разные эффекты. $( ) делает по существу одно и то же, но не является визуально двусмысленным.

Кроме того, я предполагаю, что ${FOLDER} является переменной на локальном компьютере, поэтому ее необходимо развернуть сразу (и я добавил к ней одиночные кавычки, если она содержит пробелы или другие метасимволы оболочки); если он должен быть расширен удаленной оболочкой, вместо этого используйте \"\${FOLDER|/other_folder\" . На самом деле, одинарные кавычки вокруг ${FOLDER} не будут работать, если они содержат какие-либо одиночные кавычки. Есть способ исправить это, но я здесь не беспокоился.

Вы также можете использовать одиночные кавычки в назначении переменных, но тогда у вас возникнут проблемы с одиночными кавычками в команде awk (нет чистого способа вставить одиночные кавычки в строку с одной кавычкой), и нет чистой способ расширения ${FOLDER} на локальном компьютере. Они разрешимы при смешанном цитировании, но это грязно.

Наконец, когда вы используете переменную, вы должны заключить ее в двойные кавычки:

 ssh -t user@server "$RM_CMD" 

… это не должно иметь значения в данном конкретном случае, но есть всевозможные вещи, которые могут пойти не так, как с ссылками на не двойные кавычки, так что, как правило, хорошей практикой является двойная цитата.

Вы можете проверить распространенные ошибки в сценариях bash с помощью ShellCheck , который работает в Интернете, но также доступен как автономная программа . Он поддерживает различные оболочки (идентифицируется shebang) и дает также предупреждения стилистика (например, в вашем случае использовать $(...) вместо backticks. Вы также можете редактировать текст вставляемого кода и посмотреть, как он оценивается (полезно в комбинации с обычными учебниками по стилю кодирования).