LINUX.ORG.RU
ФорумAdmin

Возник вопрос про >/>> bash

 ,


0

1

Доброго времени суток , вот мне интересно , как на системном уровне работают cимволы пренаправления в файл? например вот такая строчка echo «text» >> text.txt , как это работать на системном уровне ? я то понимаю что это допишет текст в файл , но , как он поймет что нужно дописать текст ниже определенной строки и т д ?



Последнее исправление: echo_ (всего исправлений: 1)

Ты хочешь, чтобы тебе тут рассказали, как земля была плоская и мастодонты бороздили просторы большого театра? Выучи С и вэлкам:

https://git.savannah.gnu.org/cgit/bash.git

Pyzia ★★★★★
()

>> пишет в конец файла, понятия строчек тут нет.
кстати именно bash тут не причем. это и на command.com так же работает.

anc ★★★★★
()
Последнее исправление: anc (всего исправлений: 1)

как он поймет

определит, где EOF, заменит его на новую строку, добавит EOF после добавленного текста.

Zomba444ok
()

ниже определенной строки

open с флагом O_APPEND, после этого любая запись будет идти в конец файла

Deleted
()

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

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

добавит EOF

EOF это состояние при чтении из файла, а не что-то, что можно добавить (в DOS вроде был такой байт, но то его проблемы).

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

Можно добавить EOF в середине файла и тот же cat встретив его выйдет.

Я так делал окончание вывода из pty - отдавал в конце EOF и cat, например, закрывался сам.

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

Пример можно? Может я что-то не так понял, но не вижу как EOF можно добавить в середину. В интерактивной сесии CTRL-D можно нажать, но это опять же оболочка обрабатывает.

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

Нет.

$ cat
1
1
2
2
^D
<= тут на самом деле символ, но ЛОР жалуется "0x4 is not a legal XML character"
3
3

Перед ^D нажат ^V чтобы ввести символ. Просто ^D обрабатывает оболочка. И скорее всего readline или какая там библиотека ввода.

Кстати на ЛОР, получается, символ конца действует!

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

Я уже не помню как именно я это делал. Суть была такая - есть pty в который валится некоторая инфа и надо было как-то сказать cat что больше ничего нет, выйди нафиг.

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

Нет.

Нет, да.

Перед ^D нажат ^V чтобы ввести символ.

Бинго! Это называется экранированием. Введите без него.

Просто ^D обрабатывает оболочка.

Какая оболочка?

И скорее всего readline

cat не зависит от libreadline.

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

Может это был ^C или ^\?

Шутка. Их он тоже кушает.

$ cat
^C
<= 0x3 is not a legal XML character
^\
<= 0x1c is not a legal XML character

anonymous
()
Ответ на: комментарий от Zmicier

Бинго! Это называется экранированием. Введите без него.

Дядя, ты дурак?

Какая оболочка?

Которая преобразует комбинации клавиш в символы или отрабатывает их.

cat не зависит от libreadline

Естественно. От него зависит оболочка.

anonymous
()
Ответ на: комментарий от Dark_SavanT

Не помню, очень давно дело было

Вы все правильно помните. А аноним сначала сам себя запутал, нагородив у себя каких-то «оболочек», что «преобразует комбинации клавиш в символы» аж через целый Ридлайн, а потом и вас.

Убедитесь сами:

# ttyecho /dev/pts/1 $'cat\n\x16\x04\n\x04'
и взгляните, что произошло на /dev/pts/1.

(\x16 — это ^V, а \x04 — ^D, если что).

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

нагородив у себя каких-то «оболочек», что «преобразует комбинации клавиш в символы»

Вообще-то если поправить первое, то второе абсолютно верно. То есть не «оболочка», а канонический режим терминала, в котором работают все программы, не меняющие режимы терминала, потому срабатывают комбинации клавиш, которые можно посмотреть набрав «stty -a»

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

Ну да, только это никак не отменяет того, что товарищ Dark_SavanT все верно помнит — cat(1) действительно завершится, если ему на вход телетайпа подать ^D.

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

Но в данном случае дурак — ты, мальчик.

Заметь. Я использовал цитату в ироничном смысле, а ты сходу перешёл к оскорблениям.

Теперь засунь в жопу свои измышления и предъявляй исходный код любой версии с анализов ^D (код 4). Исходники, как ты знаешь открыты.

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

Заметь.
Я использовал цитату в ироничном смысле, а ты сходу перешёл к оскорблениям.

Не замечаю. Это вам так кажется. У всех людей своя голова, и мыслят они по-своему.

Теперь засунь в жопу свои измышления

Ой-ой-ой.

предъявляй исходный код

Ага, щас. Кому?

Товарищу Dark_SavanT’у? Я думаю, что ему и опытной демонстрации выше довольно для того, чтобы точно вспомнить, что он таки прав — именно так, как он сказал, и он делал.

Или ва́м? Так это не нужно. Это вы же пришли сюда показать, какой вы-де умный — вот и показывайте! Если переложить эту задачку на кого-то еще, то пропадет весь эффект.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier
# ttyecho /dev/pts/1 $'cat\n\x16\x04\n\x04'

У меня нет утилиты ttyecho, а устанавливать её специально для этого случая я не хочу. Поэтому я сделал немного по-другому:

$ echo -e "hello\n\x16\x04hello\n\x04hello" | cat
hello
hello
hello
$ echo -e "hello\n\x16\x04hello\n\x04hello" | hexdump -C
00000000  68 65 6c 6c 6f 0a 16 04  68 65 6c 6c 6f 0a 04 68  |hello...hello..h|
00000010  65 6c 6c 6f 0a                                    |ello.|
00000015

Как видим, cat не остановила вывод, встретив не экранированный символ с кодом 4. Но я вполне верю, что где-то cat может работать по-другому. Вопрос не в этом. Если возвратиться к тому, о чём спрашивал ТС, то стандартного символа EOF не существует. EOF — это просто конец файла или потока. А индикатором этого конца может быть что угодно. В стандартном си-заголовке stdio.h EOF определён как -1 типа int, что не может совпадать ни с одним однобайтным символом. Терминал и, возможно, некоторые консольные утилиты, не исключаю, что и некоторые версии команды cat, могут воспринимать в качестве индикатора eof символ с кодом 4. Но в любом случае, это только индикатор, которых может быть множество и которые могут меняться от реализации к реализации, а настоящий EOF — это просто конец файла/потока, а не какой-то определённый символ в этом файле/потоке.

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

Поэтому я сделал немного по-другому:
[подал не на вход телетайпа, а на стандартный вход
— и получил немного другой результат]

Вот удивительно, правда?

Но я вполне верю, что где-то cat может работать по-другому.

Вы верите, что существует cat(1), что не может прочитать двоичный файл?

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

Вы верите, что существует cat(1), что не может прочитать двоичный файл?

Если вы так сказали, то почему бы мне не верить?

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

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

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

Что за истерика? Обсуждается реальный эффект: останавливает вывод cat или нет. Я продемонстрировал факт: нет, не останавливает. Не возымело действия - споры продолжаются. Так как разумные доводы не действуют, то пытаюсь достучаться через абсолютное и окончательное доказательство. Ведь если в коде cat нет и следа останова по символу (а так и есть), то всё.

Я начинаю подозревать, что кое-кто глянул таки код и понял что сливается.

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

Что за истерика?

Аноним боится признать, что он чего-то не знал, и сумничал не по делу. Удивительно даже — никогда раньше такого за анонимами не видел.

Обсуждается реальный эффект

Бинго!

Я продемонстрировал факт: нет, [^V^D] не останавливает

А я даже вам его в ключевых словах об’яснил, а потом еще раз с другой стороны продемонстрировал. А товарищ vodz более подробно рассказал, что стоит почитать.

Не возымело действия — споры продолжаются.

И не говорите, удивлен тому немало.

Я начинаю подозревать, что кое-кто глянул таки код

Он даже в этом только что признался. :-)

понял что сливается

А вот в этом никак не признается.

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

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

Да, извиняюсь, я неправильно понял. Вы сказали:

cat(1) действительно завершится, если ему на вход телетайпа подать ^D.

Но при чём тут вообще cat? Это особенность терминала, а не cat'а. То же будет и с любой другой командой, если терминал, а совсем не команда, получит ^D и возвратит команде признак конца файла, а совсем не символ ^D.

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

Я продемонстрирую ещё раз:

$ cat > test
1
^D
2
$ cat test 
1
0x4 is not a legal XML character
2

В этом примере я создаю файл через cat, а потом его вывожу. Это объективная реальность: символ есть и после него спокойно идёт 2.

Или ты считаешь что можно нажать ^V перед командой cat test?

anonymous
()
Ответ на: комментарий от aureliano15

ИМХО товарищь либо неадекват либо понял что слился и берёт на измор, что бы плюнуля

anonymous
()
Ответ на: комментарий от aureliano15

Да, извиняюсь, я неправильно понял.

Бывает. :-)

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

Но при чём тут вообще cat?

Тов. Dark_SavanT его привел для примера:

«Я так делал окончание вывода из pty - отдавал в конце EOF и cat, например, закрывался сам» [0]

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

[0] Возник вопрос про >/>> bash (комментарий)

если терминал, а совсем не команда, получит ^D и возвратит команде

Не совсем, «терминал» все-таки штука пассивная.

Это именно сама программа. Конечно, далеко не только cat(1) — любая читающая ввод тем же образом. И соответственно искать это src/coreutils (как попытался наш упорный аноним), конечно, в высшей мере наивно. Это где-то в стандартной библиотеке, с которой она собрана. В районе read(), надо думать (хотя не уверен).

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

Я продемонстрирую ещё раз

Я не знаю, что́ вы тут сделали. Вы решили на этот раз промолчать.

Хотя в прошлый раз таки признались, что прибегли к возможности экранирования символа.

Это объективная реальность: символ есть

Да, экранирование — это об’ективная реальность. Она даже должна быть документирована.

Давайте еще раз по складам, что бы вы не забыли, что погуглить: эк-ра-ни-ро-ва-ни-е. Оно специально придумано, чтобы иметь возможность вводить символы, которые иначе бы имели особое значение. :-)

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

«терминал» все-таки штука пассивная.

Отнюдь нет. Скорее наоборот.

Это именно сама программа. Конечно, далеко не только cat(1) — любая читающая ввод тем же образом. И соответственно искать это [skip] В районе read(), надо думать (хотя не уверен).

См., например, http://fliplinux.com/ctrl-d-eof.html :

Символ ^D (aka \04 или 0x4) является значением по умолчанию для специального символьного параметра eof терминала или псевдотерминального драйвера в ядре (точнее о дисциплине линии tty подключенной к устройству последовательного или псевдо-tty ). Это c_cc[VEOF] структуры termios переданной в TCSETS / TCGETS ioctl выдает на терминальное устройство проблемы, влияющие на поведение драйвера.

Типичной командой, которая отправляет эти ioctls является команда stty .

Чтобы получить все параметры:

 $ stty -a
 скорость 38400 бод;  строки 58;  столбцы 191;  line = 0;
 intr = ^ C;  quit = ^ \;  erase = ^ ?;  kill = ^ U;  eof = ^ D ;  eol = <undef>;  eol2 = <undef>;  swtch = <undef>;  start = ^ Q;  stop = ^ S;  susp = ^ Z;  rprnt = ^ R;  werase = ^ W;  lnext = ^ V;  flush = ^ O;
 min = 1;  time = 0;
 -parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
 -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel iutf8
 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
 Исходный текст

Этот параметр eof имеет значение только тогда, когда терминальное устройство находится в режиме icanon .

В этом режиме драйвер терминала (а не эмулятор терминала) реализует очень простой редактор строк , где вы можете ввести Backspace для стирания символа, Ctrl-U, чтобы удалить всю строку … Когда приложение читает с терминала, он ничего не видит, пока вы не нажмете Return, в этот момент read() возвращает полную строку, включая последний символ CR или LF (по умолчанию драйвер терминала также переводит CR в LF ).

Теперь, если вы хотите отправить то, что вы набрали до сих пор, не нажимая Enter , вы можете ввести символ eof . После получения этого символа из эмулятора терминала драйвер терминала отправляет текущее содержимое строки, так что приложение, выполняющее read на нем, получит его как есть (и оно не будет содержать CR символ LF или CR ).

Теперь, если текущая строка пуста и при условии, что приложение полностью прочитает ранее введенные строки, read вернет 0 символов.

Это означает, что конец файла для приложения (когда вы читаете из файла, вы читаете, пока нечего читать). Вот почему он называется eof , потому что его отправка заставляет приложение видеть, что больше нет ввода.

Теперь современные оболочки в своем приглашении не устанавливают терминал в режиме icanon потому что они реализуют собственный редактор строк, который намного более продвинут, чем встроенный драйвер терминала. Однако в своем собственном редакторе строк , чтобы избежать путаницы пользователей, они дают символ ^D (или что бы то ни было настройку eof терминала) того же значения (чтобы обозначить eof ).

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

Я думал типа b.write(a.read())

Непонятная строчка. И зачем что-то читать, если и fopen(), и более низкоуровневая open() позволяет открыть файл для добавления, сразу перемещая указатель на конец файла?

aureliano15 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.