Создать псевдоним из stdout

Я пытаюсь динамически создать псевдоним из вывода другого инструмента командной строки.

Например:

> MyScript
blender="/opt/apps/blender/blender/2.79/blender"
someOtherAlias="ls -l"

Я пробую следующий код:

MyScript | {
   while IFS= read -r line;
   do
      `echo alias $line`;
   done;
}

Но когда я запускаю это, я получаю следующую ошибку:

bash: alias: -l": not found

Просто попытка запустить эту команду сама по себе дает мне ту же ошибку:

> `echo 'alias someOtherAlias="ls -l"'`
bash: alias: -l": not found

Но очевидно, что следующая команда действительно работает:

alias someOtherAlias="ls -l"

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

Буду признателен за любую помощь. Спасибо!

что вы вместо этого не используете source на MyScript?

cdarke 26.10.2018 10:43

MyScript на самом деле является сокращением для сценария python, который считывает и обрабатывает кучу файлов .ini, а затем выводит результаты на стандартный вывод.

bvz 26.10.2018 18:42
0
2
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Посмотрите, как работает синтаксический анализ и цитирование команд bash (и posix shell), и увидите разницу между синтаксисом и буквальным аргументом: например, '.."..'"..'.." - это буквенные кавычки в аргументе, тогда как " или ' являются синтаксисом оболочки и не являются частью аргумента

Кроме того, включение тейсинга с помощью set -x может помочь понять:

set -x
`echo 'alias someOtherAlias="ls -l"'`
++ echo 'alias someOtherAlias="ls -l"'
+ alias 'someOtherAlias="ls' '-l"'
bash: alias: -l": not found

bash видит 3 слова: alias, someOtherAlias="ls и -l". и псевдоним перебирает свои аргументы, если они содержат =, он создает псевдоним, в противном случае он отображает аргумент псевдонима, поскольку -l" не является псевдонимом, он показывает ошибку.

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

eval можно использовать для переинтерпретации литерала как синтаксиса bash (или для повторного синтаксического анализа строки).

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

eval 'alias someOtherAlias="ls -l"'

Наконец, также как команды bash после pipe также запускаются в подоболочке.

while IFS= read -r line;
do
    `echo alias $line`;
done <MyScript

Спасибо! Это было очень полезно. Я вернусь к использованию eval. Я избегал этого, потому что он казался одновременно неуклюжим и небезопасным. Но у меня уже есть код как в этом сценарии оболочки, который я пытаюсь написать, так и в «MyScript», который проверяет всю цепочку, чтобы убедиться, что они принадлежат root и доступны для записи только root.

bvz 26.10.2018 18:46

После дальнейшего прочтения вашего ответа может показаться, что даже если я использую eval, я не получу то, что хочу, из-за того, что команды bash после pipe выполняются в подоболочке. Казалось бы, лучше всего было бы полностью собрать полную многострочную (с отдельными командами, разделенными символом ';') команду bash в «MyScript» и передать ее обратно через stdOut для оценки в моем сценарии. Пока MyScript и все его входные данные принадлежат root и доступны для записи только root, я думаю, это должно быть относительно нормально.

bvz 26.10.2018 22:16

Другие вопросы по теме