Это потому, что переменная расширяется после того, как трубы и перенаправление уже выполнены. Таким образом, в этом случае |
является еще одним аргументом echo
, а не трубой, интерпретируемой оболочкой.
Рекомендуемое чтение: http://mywiki.wooledge.org/BashFAQ/ 050
При выполнении команды
echo hello man | awk '{print $1}'
оболочка увидит |
и настроит конвейер, с одной стороны он выполнит команду echo hello man
а с другой awk '{print $1}'
. Затем команды подвергаются разбиению слов, поэтому вы запускаете команду echo
с двумя аргументами: hello
и man
. С другой стороны вы запускаете команду awk
с одним аргументом (из-за цитирования) "{print \$1}"
Когда эта команда сохраняется как строка, хотя оболочка сначала смотрит на команду $y
и не видит перенаправления. Затем он расширяет $y
, а затем разбивает на нем слово. Он расширяется до той же строки, но теперь слишком поздно для перенаправления. Поэтому он делится на слова echo
, hello
, man
, |
, awk
, "{print
, \$1}"
(обратите внимание, что теперь аргумент awk
разделяется, потому что кавычки внутри строка является частью строки, а не синтаксической)
Первое слово в этом списке - echo
, так что это команда, и все остальные слова передаются в качестве аргументов, поэтому вы видите выход
hello man | awk "{print \$1}"
Когда вы делаете строку eval
, она принимает ту же строку и сообщает bash
для ее синтаксического анализа, как если бы она была напечатана так, что труба снова станет синтаксической и вызывает [. g7]
Поскольку echo
помещает свои аргументы в одну строку, иногда бывает немного сложнее увидеть, что происходит, если мы заменим его на printf '%s\n'
, каждый аргумент станет его собственной строкой:
$ y='printf %s\n hello man | awk "{print \$1}"'
$ $y
hello
man
|
awk
"{print
\$1}"
Задание для строковых потоков, см. его в прямом эфире: http://ideone.com/e8GjMg
#include <sstream>
#include <iostream>
int main()
{
std::istringstream iss(" abcd 1234 -6242 1212");
std::string s;
int a, b, c;
iss >> s >> a >> b >> c;
std::cout << s << " " << a << " " << b << " " << c << std::endl;
}
Печать
abcd 1234 -6242 1212