Почему эхо игнорирует мои символы кавычки?

Много текстовых редакторов сохраняют файлы резервных копий. Если Вы действительно удачливы, могло бы быть что-то как yourfile.tex ~ включая предыдущую версию Вашего файла.

24
15.11.2011, 20:14
5 ответов

Ваша оболочка интерпретирует кавычки, обоих ' и ", прежде чем они даже доберутся до echo. Я обычно просто поместил двойные кавычки вокруг своего аргумента эху, даже если они являются ненужными; например:

$ echo "Hello world"
Hello world

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

$ echo \'Hello world\'
'Hello world'

Или они уже должны использоваться в заключенном в кавычки аргументе (но это не может быть тот же вид кавычки, или необходимо будет выйти из него так или иначе):

$ echo "'Hello world'"
'Hello world'

$ echo '"Hello world"'
"Hello world"

В Вашем втором примере Вы выполняете замену команды посреди строки:

grep  $ARG  /var/tmp/setfile  | awk {print $2}

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

grep /var/tmp/setfile | awk {print}

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

Этого не произойдет, если Вы одинарная кавычка аргумент (который является, почему Ваш первый пример, почти обработанный), таким образом, это - один способ получить вывод, Вы хотите:

echo \'' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `    '\'

Вы можете также двойная кавычка это, но затем необходимо будет выйти $s, таким образом, оболочка не разрешает их как переменные и обратные галочки, таким образом, оболочка не выполняет замену команды сразу же:

echo "' echo PARAM=\`  grep  \$ARG  /var/tmp/setfile  | awk '{print \$2}' \`    '"
33
27.01.2020, 19:41

Я не собираюсь вдаваться в большое количество подробностей о том, почему Ваши попытки ведут себя способ, которым они делают, потому что ответ Michael Mrozek касается этого хорошо. Короче говоря все между одинарными кавычками ('…') интерпретируется буквально (и в особенности первое ' отмечает конец литеральной строки), тогда как ` и $ сохраните их особое значение между "…".

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

echo 'foo'\''bar'

Это печатает foo'bar, потому что аргумент echo сделан из единственно заключенной в кавычки трех символьных строк foo, связанный с отдельным символом ' (полученный путем защиты символа ' от его особого значения до предыдущего \), связанный с единственно заключенной в кавычки тремя символьными строками bar. Таким образом, хотя это не совсем, что происходит негласно, можно думать '\'' как способ включать одинарную кавычку в единственно заключенной в кавычки строке.

Если Вы хотите распечатать сложные многострочные строки, лучший инструмент здесь документ. Здесь документ состоит из этих двух символов << сопровождаемый маркером такой как <<EOF, затем некоторые строки текста, затем один только маркер конца на его строке. Если маркер заключается в кавычки всегда ('EOF' или "EOF" или \EOF или 'E ""' или …), затем текст интерпретируется буквально (как внутренние одинарные кавычки, за исключением того, что даже ' обычный символ). Если маркер не заключается в кавычки вообще, то текст интерпретируется как в дважды заключенной в кавычки строке, с $\` сохранение их особого статуса (но " и новые строки интерпретируются буквально).

cat <<'EOF'
echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `
EOF
7
27.01.2020, 19:41

Хорошо, это будет работать:-

echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '\''{print $2}'\'' `    '

Тестирование его здесь:-

[asmith@yagi ~]$ echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '\''{print $2}'\'' `    '
 echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' ` 
1
27.01.2020, 19:41

Давайте примем Ваше управление

$ echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `    '

и сначала разделение это в слова, использование закрыло кавычки пробел как разделитель:

Arg[1]=“' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print”
Arg[2]=“$2}' `    '”

Затем, мы делаем расширение параметра: расшириться $… но не внутри '…'. С тех пор $2 пусто (если Вы не устанавливаете его через, например. set -- …), это будет заменено пустой строкой.

Arg[1]=“' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print”
Arg[2]=“}' `    '”

Затем, заключите удаление в кавычки.

Arg[1]=“ echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk {print”
Arg[2]=“} `    ”

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

“ echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk {print } `    ”

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

$ echo ' echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '\''{print $2}'\'' `    '

Это закончит единственно заключенную в кавычки строку, затем добавить (завершенную) одинарную кавычку к слову, затем запустить новую единственно заключенную в кавычки строку, все, не разбивая слово.

-1
27.01.2020, 19:41

Предложение Жиля об использовании здесь документа действительно хорошее, и оно работает даже в языках сценариев, таких как Perl. В качестве конкретного примера, основанного на его ответе на проблему OP,

use strict;
my $cmd = q#cat <<'EOF' # . "\n" .
          q#echo PARAM=`  grep  $ARG  /var/tmp/setfile  | awk '{print $2}' `# . "\n" .
          q#EOF# ;
open (my $OUTPUT, "$cmd |");
print $_ while <$OUTPUT>;
close $OUTPUT;

Конечно, этот пример немного надуманный, но я нашел его полезным методом, скажем, для отправки операторов SQL в psql ] (вместо cat ).

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

0
27.01.2020, 19:41

Теги

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