LINUX.ORG.RU

sh -c 'foo | 1>bar'

 , , ,


0

1

Очепятался при наборе команды:

$ foo | 2>/dev/null

Не получил ошибку и стало интересно. Как sh вычисляет такие выражения?

Почему такое

$ sh -c 'foo |'
sh: -c: line 1: syntax error: unexpected end of file
$ foo |
>
приводит к ошибке или приглашению завершить ввод. А такое:
$ sh -c 'foo | 1>bar'
$ foo | 1>bar
не приводит? Мне для понимания.

★★

Последнее исправление: Evenik (всего исправлений: 4)
Ответ на: комментарий от x22

Потому что одно это выражение правильное

Да, но почему? Поясните пожалуйста. Что оно означает изолировано и за пайпом? Чей вывод перенаправляется?

Evenik ★★
() автор топика
Последнее исправление: Evenik (всего исправлений: 1)
Ответ на: комментарий от Evenik

$ >bar открывает на запись файл bar и пишет в него stdout оболочки. У *sh на stdout ничего нет, поэтому файл открывается на запись с начала и закрывается. Поэтому это само по себе правильная команда.

Если написать, например, echo 123 | >bar, то sh ищет задачу, которой на stdin надо направить stdout echo 123. Перед > ничего нет, значит запускать нечего, >bar просто выполняется sh, как в примере без |.

// Тут есть спецы, которые вам распишут определение грамматики sh по памяти. Пользуюсь sh больше 20 лет, правил не знаю, знаки препинания расставляю в среднем правильно.

x22 ★★
()
Ответ на: комментарий от x22

$ >bar открывает на запись файл bar и пишет в него stdout оболочки

Странно как-то. Зачем так, если:

У *sh на stdout ничего нет

Пользуюсь sh больше 20 лет, правил не знаю, знаки препинания расставляю в среднем правильно

Вот и я тоже. Будем тогда ждать спецов.

Evenik ★★
() автор топика
Последнее исправление: Evenik (всего исправлений: 1)
Ответ на: комментарий от x22

Правило выглядит как {expr} > {expr}, где expr может быть пустым.

Работает только в одном случае:

$ >
-bash: syntax error near unexpected token `newline'
$ echo >
-bash: syntax error near unexpected token `newline'
$ > foo
$
Evenik ★★
() автор топика
Последнее исправление: Evenik (всего исправлений: 1)
Ответ на: комментарий от Evenik

Ну классика же! Хочешь побыстрому создать один пустой файл — пиши >file.txt. Надо несколько, тогда touch.

Как выше объяснили: ничего > файл.

papin-aziat ★★★★★
()

foo |
>

Пока спецы не подошли, вангану. Не всегда newline работает как команда «выполнить», и мне кажется это вот тот самый случай. Наверное так работает readline или типа того. Примеров можно много привести, но самый простой — \.

sh -c ‘foo |’

А здесь скрипт, он не умеет ждать ввод, вот и ошибка.

papin-aziat ★★★★★
()
Ответ на: комментарий от Evenik
$ >
-bash: syntax error near unexpected token `newline'

{expr1} > {expr2}, где expr1 может быть пустым, а expr2 должно возвращать непустой дескриптор или имя файла.

x22 ★★
()
Ответ на: комментарий от vodz

Рассматривайте это как sh -c 'foo | true 1>bar'

А можно ссылку, где про это почитать? (На более точное место, чем целиком документация или исходники.)

Evenik ★★
() автор топика
Ответ на: комментарий от Evenik

Словами здесь, например: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html

На более точное место, чем целиком документация или исходники.

^^^ В конце страницы после «/*———————-» формальное определение грамматики.

x22 ★★
()
Последнее исправление: x22 (всего исправлений: 1)
Ответ на: комментарий от Evenik

Непонятно зачем так пристально изучать мало того что нестандартные так и совершенно бесполезные конструкции как эта? Понятия не имею где почитать, но теоретически в документации сказано, что если команда не указана а есть перенаправление, то эта конструкция создаёт пустой указанный файл. А так как после | синтаксис ожидает команду, то ну и вот.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Непонятно зачем

Just for fun.

совершенно бесполезные

Это самое любимое.

Из документа по ссылке выше узнал, что возможны перенаправления в префиксе:

$ >foo echo bar
$ cat foo
bar

Я познаю мир)

Evenik ★★
() автор топика
Ответ на: комментарий от vodz

Рассматривайте это как sh -c ‘foo | true 1>bar’

Ещё и от шелла зависит.

Команды:

ls | >test
cat test

В zsh выдаёт содержимое каталога. В bash — пустой файл.

CrX ★★★★★
()
Ответ на: комментарий от CrX

В zsh выдаёт содержимое каталога. В bash — пустой файл.

zsh% emulate sh

x22 ★★
()
Ответ на: комментарий от CrX

sh -c ‘foo | true 1>bar’

Ещё и от шелла зависит.

Если sh указывает на zsh, то zsh запускается в posix mode. Другие шеллы (кроме *csh, возможно) тоже должны.

x22 ★★
()
Ответ на: комментарий от Evenik
$ >
-bash: syntax error near unexpected token `newline'

% (>:)

Пустое справа надо явно указать.

x22 ★★
()
Ответ на: комментарий от Evenik

Из документа по ссылке выше узнал, что возможны перенаправления в префиксе:

Можно то можно, но такая конструкция разве что любима странным искателем симметрии и мнимой красоты, но используется обычно для указания всё же в основном для входного файла, а не выходного, ибо тут то наоборот нарушение симметрии и красоты.

Но если уж так хотите действительно получить пользу, то попробуйте ответить на вопрос, когда эта конструкция действительно может дать один из эффектов, который возможно раз в столетие пригодиться. Я придумал, но сразу предупреждаю — задачка сложная.

vodz ★★★★★
()
Ответ на: комментарий от x22

{expr1} > {expr2}, где expr1 может быть пустым, а expr2 должно возвращать непустой дескриптор или имя файла.

ЗЫ

expr2 тоже может быть пустым, то есть ‘:’.

x22 ★★
()

$ foo | 2>/dev/null

Шел выдал ошибку, но она ушла (stderr) в /dev/null

$ bash -c 'true |'
bash: -c: line 2: syntax error: unexpected end of file

$ bash -c 'true | 2>/dev/null'
$
futurama ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.