Почему (и как) использование cat в двоичных файлах испортило терминал?

8

Если я catправильно понимаю руководство:

объединять файлы и печатать на стандартном выводе

catпримет файлы в качестве аргумента и выведет их на стандартный вывод.
То, что я не получаю, это если я использую команду:

cat img.png > copy.png

Я получу 2 PNG-файла, идентичные, а если я просто

cat img.png  

У меня есть все шансы, что мой терминал испортится и неправильно истолковывает то, что я печатаю.

  • Как это возможно?
  • Двоичные значения по-прежнему являются двоичными данными. Почему он просто не показывает последовательность из 0 и 1, или интерпретацию этих двоичных данных в ASCII, или какова бы ни была кодировка в терминале?
  • Возможно ли такое поведение, catиспользуя текстовый файл, содержащий странные символы?
  • Должен ли быть реализован механизм предотвращения такого поведения, такой как оператор try {} catch {}?
Kiwy
источник
2
Ваш терминал не запутался. Он находится в состоянии, в которое вы его принудили, отправив управляющие символы. То, что вы больше не можете использовать его после изменения состояния, может быть не тем, что вы хотели, но это полностью результат того, что вы не понимаете последствий своих действий. Это было бы то же самое, что переключить ваш цвет шрифта на зеленый в текстовом процессоре и сказать, что ваш текстовый процессор испорчен, только потому, что вы не знаете, как переключить его обратно на черный шрифт без, например, выхода из программы.
Anthon
4
resetкоманда может помочь иногда, но это не чудо решения.
Ouki
Фактическая последовательность ввода - Control-J, сбросить Control-J. Почти всегда восстанавливает здравомыслие.
Джошуа
1
@Joshua А в чем разница между одиночкой resetи нажатием resetклавиш Ctrl-J? Я не вижу ни одной (ни какой-либо причины пойти более сложным путем)
syntaxerror
1
Потому что, если терминал был оставлен в режиме RAW, Enter генерирует Ctrl-M вместо Ctrl-J, поэтому оболочка не видит необходимого нажатия клавиши для завершения строки и запуска команды.
Джошуа

Ответы:

8

cat объединяет файлы, заданные в качестве аргументов в командной строке, со стандартным выводом, он читает байты за раз и по умолчанию не выполняет никакой интерпретации байтов, которые он читает.

В первом примере вы перенаправляете стандартный вывод в файл, поэтому вы получаете новый файл.

Во втором примере байты записываются в терминал, и это терминал, который интерпретирует последовательности символов как управляющие последовательности для терминала, поэтому на вашем терминале происходит необычное поведение. Он не имеет ничего общего с catэтим, catне знает, что вы собираетесь делать с его выходом. Возможно, вы отправляете его через канал в другую программу для интерпретации / обработки / печати или воспроизведения "Поющих под дождем".

Итак, следуя философии Unix,

делай одно, делай только одно, но делай это хорошо

cat не следует пытаться угадать, что вы пытаетесь сделать.

edit 1 ответ на первый комментарий @ kiwy ниже.

Да и нет, позвольте мне объяснить,

Нет, если вы catподключены к терминалу, потому что он (программное обеспечение терминала) отправляет вывод на ваш экран или интерпретирует управляющие последовательности (он эмулирует старую часть оборудования, т. Е. Устройство телетайпа ).

но,

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

посмотрите на это в качестве примера, cat anyOldShellScript | bashbash будет интерпретировать то, что получает, как команды.

X Тянь
источник
Означает ли это, что если вы catдвоичные файлы, которые могут содержать в простой текстовой инструкции, как rm -rf .это может быть интерпретировано?
Kiwy
Я принимаю ответ, хотя на самом деле не понимаю, почему терминал может запутаться так, как если бы я набирал как тупица на клавиатуре, мне так и не удалось получить это: D
Kiwy
А теперь ирония ... гул
Kiwy
1
Управляющие символы @Kiwy не существуют на вашей клавиатуре, но вы можете echoвыводить их по своему усмотрению . См. Stackoverflow.com/questions/5947742/… чтобы узнать, как это сделать, и терминysys.demon.co.uk/vtansi.htm, чтобы узнать о том, что это возможно
Дэвид Уилкинс,
@DavidWilkins, эй, спасибо, это здорово, так много вещей, которые нужно выучить, и нет времени на это :-(
Kiwy
2

Я думаю, это происходит в основном из-за непечатаемых символов с кодами ниже 0x20. Это специальные управляющие / escape-коды, которые используются для таких клавиш, как Backspace, Delete и т. Д.

УВВ
источник