Получится ли одновременно передать команде файл на stdin и вывести ее stdout в другой файл

Обновлено: 01.10.2022

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

Домашнее задание к занятию "3.2. Работа в терминале, лекция 2"

1. Какого типа команда cd?

2. Какая альтернатива без pipe команде grep | wc -l?

3. Какой процесс с PID 1 является родителем для всех процессов в вашей виртуальной машине Ubuntu 20.04?

4. Как будет выглядеть команда, которая перенаправит вывод stderr ls на другую сессию терминала?

5. Получится ли одновременно передать команде файл на stdin и вывести ее stdout в другой файл? Приведите работающий пример.

6. Получится ли вывести находясь в графическом режиме данные из PTY в какой-либо из эмуляторов TTY? Сможете ли вы наблюдать выводимые данные?

Нужно быть авторизованным в этом терминале. Или под root без авторизации.

7. Выполните команду bash 5>&1. К чему она приведет? Что будет, если вы выполните echo netology > /proc/$$/fd/5? Почему так происходит?

bash 5>&1 запустит экземпляр bash с fd 5 и перенаправит его на fd 1 (stdout).

echo netology > /proc/$$/fd/5 выведет в терминал слово "netology". Это произойдёт потому что echo отправляет netology в fd 5 текущего шелла (подсистема /proc содержит информацию о запущенных процессах по их PID, $$ - подставит PID текущего шелла)

8. Получится ли в качестве входного потока для pipe использовать только stderr команды, не потеряв при этом отображение stdout на pty?

9. Что выведет команда cat /proc/$$/environ? Как еще можно получить аналогичный по содержанию вывод?

Команда выведет набор переменных окружения.

Что-то похожее вернут команды env и printenv .

10. Используя man, опишите что доступно по адресам /proc//cmdline, /proc//exe.

/proc//cmdline выведет команду, к которой относится , со всеми агрументами, разделёнными специальными символом '\x0' (это не пробел, cat файла выведёт всё "слипнувшимся")

/proc//exe это симлинк на полный путь к исполняемому файлоу, из которого вызвана программа с этим пидом

11. Узнайте, какую наиболее старшую версию набора инструкций SSE поддерживает ваш процессор с помощью /proc/cpuinfo.

12. При открытии нового окна терминала и vagrant ssh создается новая сессия и выделяется pty. Однако . not a tty . Почитайте, почему так происходит, и как изменить поведение.

Это сделано для правильной работы в скриптах. Если сразу выполнить команду на удалённом сервере через ssh, sshd это поймёт, и запускаемые команды тоже, поэтому они не будут спрашивать что-то у пользователя, а вывод очистят от лишних данных.

Например, если в интерактивном режиме программа задала бы пользователю вопрос и ждала ответа "yes/no", при запуске через ssh она этого делать не станет.

Изменить поведение можно добавив флаг -t при вызове ssh.

13. Бывает, что есть необходимость переместить запущенный процесс из одной сессии в другую. Попробуйте сделать это, воспользовавшись reptyr.

Работает по инструкции проекта reptyr.

14. Узнайте что делает команда tee и почему в отличие от sudo echo команда с sudo tee будет работать.

Команда tee делает вывод одновременно и в файл, указанный в качестве параметра, и в stdout . В данном примере команда получает вывод из stdin , перенаправленный через pipe от stdout команды echo и т.к. команда запущена от sudo , соответственно имеет повышенные права на запись.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

С каждым открытым файлом связан дескриптор файла. [1] Дескрипторы файлов stdin, stdout и stderr -- 0, 1 и 2, соответственно. При открытии дополнительных файлов, дескрипторы с 3 по 9 остаются незанятыми. Иногда дополнительные дескрипторы могут сослужить неплохую службу, временно сохраняя в себе ссылку на stdin, stdout или stderr. [2] Это упрощает возврат дескрипторов в нормальное состояние после сложных манипуляций с перенаправлением и перестановками (см. Пример 16-1).

Операции перенаправления и/или конвейеры могут комбинироваться в одной командной строке.

Допускается перенаправление нескольких потоков в один файл.

Закрытие дескрипторов файлов

Закрыть дескриптор входного файла n.

Закрыть дескриптор выходного файла n.

Дочерние процессы наследуют дескрипторы открытых файлов. По этой причине и работают конвейеры. Чтобы предотвратить наследование дескрипторов -- закройте их перед запуском дочернего процесса.

Дополнительные сведения о перенаправлении ввода/вывода вы найдете в Приложение D.

Команда exec перенаправляет ввод со stdin на файл. С этого момента весь ввод, вместо stdin (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.

Пример 16-1. Перенаправление stdin с помощью exec

Аналогично, конструкция exec >filename перенаправляет вывод на stdout в заданный файл. После этого, весь вывод от команд, который обычно направляется на stdout, теперь выводится в этот файл.

Пример 16-2. Перенаправление stdout с помощью exec

Пример 16-3. Одновременное перенаправление устройств, stdin и stdout, с помощью команды exec

Примечания

дескриптор файла -- это просто число, по которому система идентифицирует открытые файлы. Рассматривайте его как упрощенную версию указателя на файл.

С каждым открытым файлом связан дескриптор файла. [1] Дескрипторы файлов stdin, stdout и stderr -- 0, 1 и 2, соответственно. При открытии дополнительных файлов, дескрипторы с 3 по 9 остаются незанятыми. Иногда дополнительные дескрипторы могут сослужить неплохую службу, временно сохраняя в себе ссылку на stdin, stdout или stderr. [2] Это упрощает возврат дескрипторов в нормальное состояние после сложных манипуляций с перенаправлением и перестановками (см. Пример 16-1).

Операции перенаправления и/или конвейеры могут комбинироваться в одной командной строке.

Допускается перенаправление нескольких потоков в один файл.

Закрытие дескрипторов файлов

Закрыть дескриптор входного файла n.

Закрыть дескриптор выходного файла n.

Дочерние процессы наследуют дескрипторы открытых файлов. По этой причине и работают конвейеры. Чтобы предотвратить наследование дескрипторов -- закройте их перед запуском дочернего процесса.

Дополнительные сведения о перенаправлении ввода/вывода вы найдете в Приложение D.

Команда exec перенаправляет ввод со stdin на файл. С этого момента весь ввод, вместо stdin (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.

Пример 16-1. Перенаправление stdin с помощью exec

Аналогично, конструкция exec >filename перенаправляет вывод на stdout в заданный файл. После этого, весь вывод от команд, который обычно направляется на stdout, теперь выводится в этот файл.

Пример 16-2. Перенаправление stdout с помощью exec

Пример 16-3. Одновременное перенаправление устройств, stdin и stdout, с помощью команды exec

Примечания

дескриптор файла -- это просто число, по которому система идентифицирует открытые файлы. Рассматривайте его как упрощенную версию указателя на файл.

Какого типа команда cd ? Попробуйте объяснить, почему она именно такого типа; опишите ход своих мыслей, если считаете что она могла бы быть другого типа.

Какая альтернатива без pipe команде grep | wc -l ? man grep поможет в ответе на этот вопрос. Ознакомьтесь с документом о других подобных некорректных вариантах использования pipe.

Какой процесс с PID 1 является родителем для всех процессов в вашей виртуальной машине Ubuntu 20.04?

Как будет выглядеть команда, которая перенаправит вывод stderr ls на другую сессию терминала?

Получится ли одновременно передать команде файл на stdin и вывести ее stdout в другой файл? Приведите работающий пример.

Получится ли вывести находясь в графическом режиме данные из PTY в какой-либо из эмуляторов TTY? Сможете ли вы наблюдать выводимые данные?

Выполните команду bash 5>&1 . К чему она приведет? Что будет, если вы выполните echo netology > /proc/$$/fd/5 ? Почему так происходит?

Ответ:
bash 5>&1 - Создаст дескриптор с 5 и перенатправит его в stdout
echo netology > /proc/$$/fd/5 - выведет в дескриптор "5", который был пернеаправлен в stdout

если запустить echo netology > /proc/$$/fd/5 в новой сесии, получим ошибку, так как такого дескриптора нет на данный момент в текущей(новой) сесии

Получится ли в качестве входного потока для pipe использовать только stderr команды, не потеряв при этом отображение stdout на pty? Напоминаем: по умолчанию через pipe передается только stdout команды слева от | на stdin команды справа. Это можно сделать, поменяв стандартные потоки местами через промежуточный новый дескриптор, который вы научились создавать в предыдущем вопросе.

Что выведет команда cat /proc/$$/environ ? Как еще можно получить аналогичный по содержанию вывод?

Используя man , опишите что доступно по адресам /proc//cmdline , /proc//exe .

Узнайте, какую наиболее старшую версию набора инструкций SSE поддерживает ваш процессор с помощью /proc/cpuinfo .

При открытии нового окна терминала и vagrant ssh создается новая сессия и выделяется pty. Это можно подтвердить командой tty , которая упоминалась в лекции 3.2. Однако:

Почитайте, почему так происходит, и как изменить поведение.

Бывает, что есть необходимость переместить запущенный процесс из одной сессии в другую. Попробуйте сделать это, воспользовавшись reptyr . Например, так можно перенести в screen процесс, который вы запустили по ошибке в обычной SSH-сессии.

sudo echo string > /root/new_file не даст выполнить перенаправление под обычным пользователем, так как перенаправлением занимается процесс shell'а, который запущен без sudo под вашим пользователем. Для решения данной проблемы можно использовать конструкцию echo string | sudo tee /root/new_file . Узнайте что делает команда tee и почему в отличие от sudo echo команда с sudo tee будет работать.

ls | echo ничего не выводит (пустая строка, фактически). Я ожидаю, что он распечатает список файлов.

ls | grep 'foo' , с другой стороны, работает как ожидалось (печатает файлы с именем «foo» в их имени).

То, что я делаю в этих ситуациях, это что-то вроде: ls | while read OUT; do echo $OUT; done , но это довольно громоздко.

Почему трубопровод работает с некоторыми командами, но не с другими? Как я могу обойти эту проблему?

Примечания

дескриптор файла -- это просто число, по которому система идентифицирует открытые файлы. Рассматривайте его как упрощенную версию указателя на файл.

С каждым открытым файлом связан дескриптор файла. [1] Дескрипторы файлов stdin, stdout и stderr -- 0, 1 и 2, соответственно. При открытии дополнительных файлов, дескрипторы с 3 по 9 остаются незанятыми. Иногда дополнительные дескрипторы могут сослужить неплохую службу, временно сохраняя в себе ссылку на stdin, stdout или stderr. [2] Это упрощает возврат дескрипторов в нормальное состояние после сложных манипуляций с перенаправлением и перестановками (см. Пример 16-1).

Операции перенаправления и/или конвейеры могут комбинироваться в одной командной строке.

Допускается перенаправление нескольких потоков в один файл.

Закрытие дескрипторов файлов

Закрыть дескриптор входного файла n.

Закрыть дескриптор выходного файла n.

Дочерние процессы наследуют дескрипторы открытых файлов. По этой причине и работают конвейеры. Чтобы предотвратить наследование дескрипторов -- закройте их перед запуском дочернего процесса.

Дополнительные сведения о перенаправлении ввода/вывода вы найдете в Приложение D.

Команда exec перенаправляет ввод со stdin на файл. С этого момента весь ввод, вместо stdin (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.

Пример 16-1. Перенаправление stdin с помощью exec

Аналогично, конструкция exec >filename перенаправляет вывод на stdout в заданный файл. После этого, весь вывод от команд, который обычно направляется на stdout, теперь выводится в этот файл.

Пример 16-2. Перенаправление stdout с помощью exec

Пример 16-3. Одновременное перенаправление устройств, stdin и stdout, с помощью команды exec

4 ответа

Существует различие между аргументами командной строки и стандартным вводом. Труба подключит стандартный выход одного процесса к стандартному входу другого. Так

Соединяет стандартный вывод ls со стандартным входом эха. Хорошо? Ну, эхо игнорирует стандартный ввод и дамп его аргументы командной строки, которые в этом случае не равны, - свой собственный stdout. Результат: ничего.

В этом случае есть несколько решений. Один из них - использовать команду, которая считывает stdin и dumps в stdout, например cat.

Будет работать, в зависимости от вашего определения работы.

Но как насчет общего случая. Вы действительно хотите преобразовать stdout одной команды в командную строку args другого. Как говорили другие, xargs - это канонический вспомогательный инструмент в этом случае, считывая его аргументы командной строки для команды из своего stdin и создавая команды для запуска.

Вы также можете преобразовать это, используя команду подстановки $()

Также будет делать то, что вы хотите.

Оба этих инструмента являются довольно ядром для сценариев оболочки, вы должны изучить оба.

Для полноты, как вы указываете в вопросе, другой базовый способ преобразования stdin в командной строке args - это встроенная команда оболочки read . Он преобразует «слова» (слова, определенные переменной IFS ) в временную переменную, которую вы можете использовать в любых запусках команд.

ls | echo печатает только пустую строку, потому что echo не читает ввод; последняя команда конвейера на самом деле echo , который печатает только пустую строку.

гарантирует, что вывод a станет входом b . Я предлагаю вам прочитать раздел Pipelines man bash .

Если вы действительно хотите использовать ls и echo , вот некоторые (довольно бесполезные) примеры:

Читайте также: