Intereting Posts
Файлы устройств и драйверы диска, раздела и файловой системы? Сравнение двух строк с помощью awk Bash – настройка среды vars из строки вызова bash Как использовать ffmpeg или avconv для создания файла из исходного источника Как обновить компилятор gfortran? Как я могу дистанционно разблокировать рабочую станцию ​​RHEL7? Stat Symbolic Link: не будет отображаться исходное время изменения файла Компиляция / установка драйвера для Wifi dongle отсутствуют модули ядра? Сортировка файлов изображений на основе того, является ли контент изображением или графикой: обновление старого решения? Каковы относительные достоинства различных стандартных архивных утилит Unix? Как написать все строки от меньшего до файла? Замените определенные строки на значение из предыдущей строки Преобразование ext2 в ext4 группы захвата sed не работают файл резервной копии локально в сценарии оболочки

Расширение Bash $ {@} как команда

У меня есть родительский скрипт

while read cmd do nohup ./script ${cmd[@]} &>> log & done < ~/list 

который выполняет этот дочерний скрипт

 while true do eval "${CMD[@]}" #${CMD[@]} #./panic done 

с этим списком команд

 node ~/www/splash/app.js node ~/www/splash-two/app.js 

Когда дочерний скрипт вызывает eval ${CMD[@]} он выполняет так, как я ожидаю, запускаю эту команду без жалоб, но когда я пытаюсь удалить eval и запускаю команду, используя ${CMD[@]} она выдает ошибку:

 Error: Cannot find module '/home/rumplefraggle/SYS/RABBOT/~/www/splash/app.js' 

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

Повторяя ${@} и не запуская его, он расширяется, как я ожидал.

Также вручную вставка команды в дочерний скрипт также работает так, как ожидалось

Я не понимаю, почему работает eval и просто запускает команду с помощью ${@} . Что вызывает ${@} чтобы не расширять ~ ?

Почему узел добавляет имя каталога в команду при использовании ${@} ?

Это происходит из-за расширения тильды. Eval расширяет тильду, которая заменяется полным путем к домашнему каталогу. Без этого команда получает литеральную тильду, и пытается использовать относительный путь (которого не существует).

 $ echo ~ /home/chris $ echo "~" ~ $ eval 'echo ~' /home/chris 

Вам нужны цитаты: "${cmd[@]}"

Без кавычек все элементы массива расплываются в одну строку. С кавычками каждый элемент будет обрабатываться индивидуально.

Из руководства :

Если индексом является '@' или '*' , слово расширяется до всех членов имени массива. Эти индексы отличаются только тогда, когда слово появляется в двойных кавычках. Если слово double-quoted, […] ${name[@]} расширяет каждый элемент имени до отдельного слова.