Bash - замена Команды добавляет одинарные кавычки

. текущий каталог. : разделитель пути, используемый для разделения разнообразных путей в единственной опции/переменной под *отклоняют. Эта командная строка поэтому добавляет обоих . и zookeeper-3.4.5.jar к пути к классу Java.

3
12.04.2015, 00:51
1 ответ

Bash не добавлял одинарные кавычки к команде.Одиночные кавычки, которые вы видите, добавляются, чтобы отображаемая команда соответствовала синтаксису bash. Если вы видите

find -name '"*.log"'

, это означает, что bash было приказано выполнить эту команду: find с двумя аргументами -name и «*. Log» (двойное цитаты, являющиеся частью аргументации). Его можно было ввести точно так же или другим эквивалентным способом, например

find -name \"*.log\"
find -name "\"*.log\""
find -name '"*.'log""\"

Теперь давайте посмотрим на то, что вы написали:

find `echo "-name \"*.log\""`

Команда, выполняемая в подоболочке, -

echo "-name \"*.log\""

Ее вывод -

-name "*.log"

Вот где двойные кавычки в аргументе исходят из. Когда вывод подстановки команды интерполируется в командную строку, он не анализируется как синтаксис оболочки - поэтому, например,

find `echo '; rm -rf ~'`

не удалит все ваши файлы, а вместо этого передаст ; в качестве первого аргумента в найдите , rm в качестве второго, -rf в качестве третьего и ваш домашний каталог (при условии, что он не содержит никаких специальных символов) в качестве четвертого.

Когда подстановка переменной или команда находится вне двойных кавычек, следующие преобразования происходят со значением переменной или выводом команды:

  1. Только для подстановки команд: завершающие символы новой строки удаляются.
  2. Строка разбивается на части, разделенные пробелами. (Вы можете настроить разделители, установив переменную IFS .) Обратите внимание, что результатом этого преобразования является список строк.
  3. Каждый элемент списка интерпретируется как шаблон подстановки. Если этот шаблон соответствует файлам, то элемент заменяется списком совпадающих файлов (это называется подстановкой ).Если шаблон не соответствует ни одному файлу, элемент остается в покое.

Шаг 2 разбивает строку -name «* .log» на две части: -name и «*. Log» .Ни один из этих фрагментов не соответствует ни одному файлу, поэтому результатом являются два слова -name и «*. Log» .

Вы хотели вместо этого запустить find с аргументами -name и * .log . Вы можете сделать это, отключив подстановку:

set -f
find `echo -name *.log`
set +f

Это ненадежно: например, он не позволит вам передавать имена файлов, содержащие пробелы. Вообще говоря, вы не должны пытаться создавать команды, сохраняя их биты в переменной или передавая их в командах. Лучший способ делать то, что вы делаете, зависит от того, что вы на самом деле пытаетесь сделать. Вот несколько общих советов:

1
27.01.2020, 21:31

Теги

Похожие вопросы