Различное поведение eval "command \" $ @ \ "", "$ @" и "$ (echo $ @)" при использовании в качестве аргументов

Я хотел бы передать несколько аргументов в браузер Tor (firefox) программно через функцию, произвольно tor . Это так, чтобы командовать tor search terms и вуаля! Мои поисковые запросы. При использовании этих трех вариантов,

 ~/tor-browser_en-US/Browser/start-tor-browser -search "$(echo $@)" eval "~/tor-browser_en-US/Browser/start-tor-browser -search \"$@\"" ~/tor-browser_en-US/Browser/start-tor-browser -search "$@" 

Кажется, что только первые две строки выполняются одинаково. Они приводят к одному браузеру браузера Tor, который ищет условия произвольного текстового контента. Однако в третьей строке появляется одно новое окно поиска для каждого слова.

Почему это поведение?

Позвольте пояснить. Я не ищу обходных решений, а просто интересуюсь объяснением в отношении bahviour.

2 Solutions collect form web for “Различное поведение eval "command \" $ @ \ "", "$ @" и "$ (echo $ @)" при использовании в качестве аргументов”

Для третьей версии вы хотите "$*" не "$@" .

объяснение

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

 $ set -- arg1 arg2 arg3 

Теперь давайте прочитаем их с вашей формулировкой echo :

 $ printf "%s\n" "$(echo $@)" arg1 arg2 arg3 

Посмотрим, что с ними "$@" :

 $ printf "%s\n" "$@" arg1 arg2 arg3 

Разница в том, что "$@" расширяется до трех слов, а "$(echo $@)" расширяется до одной строки. Если вам нужно поведение типа "$(echo $@)" , вы должны использовать "$*" :

 $ printf "%s\n" "$*" arg1 arg2 arg3 

Документация

От man bash :

"$*" создает одну строку:

«$ *» эквивалентен «$ 1c $ 2c …», где c – первый символ значения переменной IFS.

Напротив, man bash утверждает, что $@ создает ряд слов:

«$ @» эквивалентен «$ 1» «$ 2» …

Использование eval

Заметим:

 $ echo 'printf "%s\n" "' "$@" '"' printf "%s\n" " arg1 arg2 arg3 " 

Когда bash оценивает команду echo , "$@" расширяется для разделения слов. echo принимает эти отдельные слова и объединяет их в одну строку. Мы видели это раньше, когда смотрим на "$(echo $@)" . Аналогично работает eval . Он выводит одну строку из всех своих аргументов и оценивает эту строку. Таким образом:

 $ eval 'printf "%s\n" "' "$@" '"' arg1 arg2 arg3 

Это также документировано man bash :

eval [arg …]
Аргенты считываются и объединяются вместе в одну команду. Затем эта команда считывается и выполняется оболочкой, …

Рассмотрим более простой пример, чтобы увидеть разницу:

 $ set "ab" c "de" $ printf "%s\n" "$@" ab c de 

Предыдущее – это то, что вы должны использовать; это просто, легко понять и исправить.

 $ printf "%s\n" "$(echo $@)" abcde 

Здесь $@ сначала расшифровывается без кавычек (кавычки, связанные с подстановкой команд, являются отдельными и еще не применены), поэтому он эквивалентен $(echo abcde) , а printf имеет один дополнительный аргумент после строки формата.

 $ eval "printf \"%s\n\" \"$@\"" abcde 

Здесь цитируется $@ , но расширение создает 3 отдельных аргумента для eval ( printf "%s\n" ab , c и de ), которые объединены в одну команду, которая производит тот же вывод, что и номер 2 выше.

  • Как найти точную строку без ведущего или конечного символа
  • Как написать скрипт bash без использования sudo в нем?
  • Невозможно выполнить сценарий Bash, если / while
  • Как преобразовать все .wav-файлы в подкаталоги в .aac, используя neroAacEnc?
  • Правильная блокировка в сценариях оболочки?
  • Получение пользовательского ввода из сценария, используемого как stdin для сеанса SSH
  • Пока команда не найдена и синтаксическая ошибка рядом с неожиданным токеном
  • использование файла lockfile в скрипте и его значение
  • В чем разница между «расширением» и «замещением» в терминах терминологии оболочки?
  • Предотвращение разрывов в середине слова в a2ps
  • Как узнать, существует ли каталог?
  • Interesting Posts

    Настольная среда, которая только запускает полноэкранный терминал

    Iptables в linux

    Что мне нужно сделать, чтобы создать быстро устанавливаемый дистрибутив Debian?

    Невозможно изменить разрешения файлов / каталогов в chrooted файловой системе

    В оболочке Fish, как я могу присоединиться к массиву с пользовательским разделителем?

    dump directory data в файл для нового / модифицированного сравнения позже на сервере linux

    Запретить некоторые IP-адреса из определенной сети на Apache?

    проанализировать учетные данные из файла конфигурации PHP

    LXC: Разница в безопасности между корневыми и конечными пользователями, не имеющими привилегированных контейнеров?

    Загрузите файл yesterdays с FTP-сервера

    Imagemagick конвертирует неправильно размеры ландшафта pdfs

    Невозможно изменить размер / dev / sda2 расширенного раздела с gparted live cd

    Могут ли ext (4?) Файловые системы хранить более новые данные в моде, более подверженном коррупции?

    Случайная система Замораживает на двух разных машинах в одной комнате

    STDOUT как аргумент в bash / Makefile и место для дескриптора правильно

    Linux и Unix - лучшая ОС в мире.