Места рядом с трубами

17

Я видел history | grep blahи history |grep blah; и history|grep blahтакже работает, хотя никто, кажется, никогда не использует его.

Есть ли какое-либо значение в пробелах (например, для передачи в / из разных команд требуется разное использование пробелов), или это всегда произвольно?

EmmaV
источник
13
Читаемость, в основном.
Джейсонвриан
1
|pipe или ;точка с запятой используются большинством shell (bash, ksh, tcsh) в качестве разделителя команд. когда не заключено в кавычки, пробелы до и после являются неуважительными.
Archemar

Ответы:

24

bashопределяет несколько метасимволов . От man bash:

метасимвол Символ,
который без кавычек разделяет слова. Одно из следующего:
| &; () <> пробел

Поскольку метасимволы разделяют слова, не имеет значения, окружены ли они пробелами. Символ трубы |, является метасимволом и, следовательно, как вы заметили, ему не нужны пробелы вокруг него.

Следует отметить , что [, ], {, }и =являются не метасимволы. Их значение, напротив, сильно зависит от того, окружены ли они пробелами.

Примеры, когда пробелы есть и не нужны

Как вы заметили, не имеет значения, |окружены ли пробелы. Давайте рассмотрим некоторые примеры, которые обычно путают пользователей bash. Рассмотреть возможность:

$ (date)
Sun Mar  1 12:47:07 PST 2015

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

$ {date}
bash: {date}: command not found

Поскольку {и не} являются метасимволами, оболочка рассматривается как одно слово. Вместо того, чтобы искать команду, она ищет команду с именем . Поскольку он не находит, возникает ошибка.{date}date{date}

Другая распространенная проблема - testкоманда. Следующее работает успешно:

$ [ abc ] && echo Yes
Yes

Удалите пробелы и произойдет ошибка:

$ [abc] && echo Yes
bash: [abc]: command not found

Потому [и ]являются не метасимволы, лечит оболочки [.bashrc]как одно слово , и результат, так же , как в dateпримере, является ошибкой.

Операторы присваивания также чувствительны к пробелам. Следующее задание выполнено успешно:

$ v=date
$ echo $v
date

Добавьте пробел и назначение завершится неудачно:

$ v= date
Sun Mar  1 12:55:05 PST 2015

В приведенном выше описании оболочка временно устанавливается vпустой и затем выполняет dateкоманду.

Добавление пробела перед =также вызывает сбой, но по другой причине:

$ v =date
bash: v: command not found

Здесь оболочка пытается выполнить команду vс аргументом =date. Ошибка в том, что не найдено ни одной команды с именем v.

John1024
источник
1
Недавно я стал жертвой заявления о назначении. У меня были пробелы до и после =. Потребовалось время для отладки.
15:00
3

Каналы позволяют использовать выходные данные программы как входные данные другой ...

Что касается пробелов, это просто вопрос читабельности / предпочтения персонала, как упомянуто @jasonwryan.

Один пробел до и после "|" это норма ....

Вы также можете использовать его с колонкой -t, чтобы сделать не только аккуратную линию, но и вывод.

lnydex99uhc:depot_r user$ lsof | grep my | column -t
Microsoft  290  user  txt  REG  1,4  9515016  170972    /Library/Fonts/PCmyoungjo.ttf
bash       359  user  cwd  DIR  1,4  714      12246074  /Users/zatef/hw2/base/active/myapp
зет
источник
2

В одном случае полезно не использовать пробелы. Если вы не используете американско-американскую раскладку, вас могут заставить использовать некоторые комбинации, например, AltShiftLдля ввода канала. Хотя это само по себе не является проблемой, одним из следствий этого является то, что иногда вы также вводите непечатаемые символы до или после этого символа. Например, на французской клавиатуре Macbook Pro мне приходится использовать AltShiftLдля ввода |. Когда вы печатаете быстро, вы можете случайно напечатать это: AltShift( L, Space)

$ sudo dmesg | tail
zsh: command not found:  tail

echo "sudo dmesg | tail" | od -a
0000000    s   u   d   o  sp   d   m   e   s   g  sp   |         t   a
0000020    i   l  nl

Если вы не знаете, что AltShiftSpaceвводит другой пробел (неразрывный пробел ( U + 00A0 )), трудно понять следующую ошибку:zsh: command not found:  tail

alecail
источник
1

Единственное значение пробелов в этом случае - эстетика.
Или, другими словами, полезно сделать команды более читабельными для человека.

asoundmove
источник