cat не работает с каналом

#bash #shell #scripting

#bash #оболочка #создание сценариев

Вопрос:

Пересмотренная версия вопроса:

 cat - | tr "a-z" "A-Z" | tr "A-Z" "a-z"
  

не выдает никаких выходных данных, когда я запускаю его в командной строке bash. Я должен нажать Ctrl-D, чтобы получить o / p.

o/p

 $ cat - | tr "a-z" "A-Z" | tr "A-Z" "a-z"
this is a test
  

Однако это работает просто отлично, и я получаю вывод без использования Ctrl-D .. Почему?

 cat - | tr "a-z" "A-Z" 
  

o/p

 $ cat - | tr "a-z" "A-Z" 
this is a test
THIS IS A TEST
  

Оригинальная версия вопроса:

 cat "$@" | tr "a-z" "A-Z" | tr "A-Z" "a-z"
  

зависает, когда я запускаю его в командной строке bash. Почему это?

Мой $@ пуст.

Однако это работает следующим образом

 cat "$@" | tr "a-z" "A-Z" 
  

Комментарии:

1. После вашей правки по удалению ссылок на «$ @» вопрос теперь не имеет смысла. Используя «-«, обе формы эквивалентны и ведут себя одинаково в том, что касается блокировки. Я думаю, вам следует восстановить предыдущую версию.

2. Я внес больше изменений, теперь я также показываю o / p.

3. @Idelic обе формы не эквивалентны. Это то, на что я пытаюсь указать.

4. Поскольку вы написали их в то время, когда я писал комментарий, они были эквивалентны с точки зрения блокировки, а не с точки зрения вывода: обе формы (с cat - ) будут блокироваться, пока вы не нажмете Ctrl-D. Если вы используете cat "$@" , они не эквивалентны с точки зрения необходимости использования Ctrl-D (они ведут себя по-разному, если $ @ пусто или нет). Ваша последняя правка немного проясняет ситуацию, и я отвечаю ниже.

Ответ №1:

Если $@ значение пусто, cat будет ожидать ввода в stdin, который привязан к вашему tty, когда вы запускаете его из командной строки. Введите ctrl-D (чтобы указать конец файла), и вы вернетесь к своей подсказке.

В скрипте $@ , вероятно, будет расширяться до имени файла, поэтому поведение отличается.

Ответ №2:

То, что вы видите, связано с буферизацией. В

 cat - | tr a-z A-Z | tr A-Z a-z
  

(кавычки не нужны) вы можете не получить выходные данные сразу после нажатия
ВВЕДИТЕ, потому что средний или третий tr , возможно, буферизовал данные
внутренне. В какой-то момент они очистят свои буферы, и вы получите
полный, корректный вывод. Нажатие Ctrl-D закрывает канал и вызывает сброс.

Это довольно типичное явление при соединении нескольких команд в одном канале.

Кстати, в этом случае (но не при использовании «$ @») cat - это лишнее.

Комментарии:

1. Да, я проверил это, введя большое количество текста (в качестве ввода-вывода в cat) Я получаю вывод с помощью конструкции two pipe, приведенной выше. Это ответ, который я искал! Спасибо.