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)

foo |
>

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

sh -c ‘foo |’

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

papin-aziat ★★★★★
()
Ответ на: комментарий от 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 ★★
() автор топика
Ответ на: комментарий от Evenik

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

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

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

vodz ★★★★★
()