Имеет ли оболочка такой же стандартный ввод, стандартный вывод, стандартная ошибка, как и все остальные команды?

Настройте файл grub. grub-mkconfig -o /boot/grub/grub.cfg .Он найдет ваш менеджер загрузки windows и добавит пункт меню загрузки для конфигурации EFI. Перезагрузите систему.

3
24.05.2017, 22:11
2 ответа

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

echo "cat filename" | bash

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

bash -c "echo foo" > filename

выполнит команду echo foo, и вывод будет перенаправлен в файл.

В Unix нет ничего «особенного» в оболочке. Это просто обычная программа, основной целью которой является выполнение других программ.

6
27.01.2020, 21:11

Различим терминологию:

Команда — это то, что вы вводите в свою оболочку. Это может быть псевдоним или функция оболочки или ссылка на исполняемый файл .

Исполняемый файл может быть двоичным исполняемым файлом (, т. е. таким, который содержит непосредственно машинный код )или сценарий . Сценарии включают сценарии bash, сценарии sh, сценарии perl, сценарии awk, сценарии sed, сценарии python и т. д. др.

Первые два байта вашего сценария (, если он должен быть выполнен непосредственно как исполняемый файл ), должны быть #!, что является «магическим числом», которое сигнализирует вашему ядру о необходимости чтения дальнейших байтов до тех пор, пока читается новая строка, интерпретируйте эти байты как путь к двоичному исполняемому файлу , возможно, с одним аргументом, разделенным пробелом (, например#!/bin/awk -f)и выполнить этот двоичный исполняемый файл , указав путь к самому скрипту в качестве аргумента.

В конечном счете, единственное, что ядро ​​действительно может выполнять, — это машинный код, т. е. двоичный исполняемый файл. Двоичные исполняемые файлы, такие как sh, bash, perl, python, awk и т. д. др. называются интерпретаторами. Они интерпретируют сценарий и выполняют его инструкции. Но они должны существовать в машинном коде, чтобы их можно было выполнить.

Когда программа (двоичный исполняемый файл )фактически запускается ядром, она существует как процесс. Бинарный исполняемый файл — это просто файл, содержащий инструкции. Процесс — это «работающий экземпляр программы»;более конкретно, это абстракция, встроенная в ядро, имеющая связанную память, переменные среды, идентификатор процесса (, PID ), файловые дескрипторы , которые он может использовать для ввода и вывода, и другие атрибуты. Вы можете запускать исполняемый файл более одного раза «одновременно» (не буквально одновременно на одной основной машине, но из-за того, как ядро ​​​​распределяет циклы ЦП, это будет казаться одновременным )и каждый запущенный экземпляр будет другим процессом, хотя все они являются экземплярами одной и той же программы.

0, 1 и 2 — стандартный ввод, стандартный вывод и стандартная ошибка — являются файловыми дескрипторами. По правде говоря, они вообще существуют только по соглашению. Вы можете создать программу, используя C, которая будет запускать (запускать )другие программы (выполнять различные двоичные исполняемые файлы ), вообще не предоставляя им эти файловые дескрипторы. Однако, поскольку все стандартные программы написаны с учетом наличия файловых дескрипторов 0, 1 и 2, вы, вероятно, не получите ничего, кроме ошибок (в большинстве случаев )и программы не будут работать корректно.

Чтобы понять это полностью, вы должны понять, как возникает процесс. Это немного похоже на чудо рождения. ; )Все процессы должны запускаться другим процессом. Не беспокоясь о том, как запускается первый процесс при загрузке системы, процесс с PID 1 называется «init», и он запускает другие основные процессы, необходимые вашей операционной системе для работы.

Как процесс запускает другой процесс с помощью двух основных шагов:fork и exec. Оба они являются системными вызовами, то есть действиями/запросами, которые процесс отправляет ядру , которые может выполнить только ядро.

«Вилка» означает (в двух словах ), «ядро,пожалуйста, сделайте копию меня». («Я» — запущенный процесс. )Ядро делает полную копию процесса — его файловых дескрипторов, памяти, состояния выполнения (, где он находится в следующем инструкции, которые содержат программу, экземпляром которой он является ), переменные окружения и т. д. Так что это "клон" процесса. Как же теперь отличить оригинал от копии? Только по одному признаку :статус возврата системного вызова fork. Дочерний процесс получает "0" (успех ), а родительский процесс получает PID только что созданного дочернего процесса. Таким образом, проверяя этот статус возврата, каждый процесс может определить что он должен делать сейчас (, потому что помните, они следуют одному и тому же набору инструкций!).

«Exec» на самом деле «execve ()». В двух словах, он просит ядро: «ядро, пожалуйста, замените меня (я процесс )экземпляром программы, указанной в файле ______». И программист также указывает аргументы , которые будут у нового процесса, и окружение(массив переменных окружения ), которые он будет иметь.

Таким образом, когда вы вводите команду в оболочку, то, что на самом деле происходит (большую часть времени, игнорируя особые случаи, такие как встроенные команды оболочки, такие как cd), заключается в том, что ваша оболочка (, которая является запущенным процессом)разветвляется, , а затем выполняет указанную вами команду.

Если вы выполнили перенаправление вывода или ввода, как /bin/echo hello > /dev/null, то разветвленный дочерний процесс перед execэхом соответствующим образом скорректирует свои файловые дескрипторы, так что файловый дескриптор 1 (в этот пример )привязан к /dev/nullвместо вашего терминала или где бы он ни был раньше.

Итак, да, любой работающий экземпляр исполняемого файла /bin/bashбудет ожидать наличия файлового дескриптора 0, из которого он может считывать ввод,файловый дескриптор 1, в который он может записывать вывод, и файловый дескриптор 2, в который он может читать и записывать сообщения об ошибках и аналогичные ввод/вывод.

3
27.01.2020, 21:11

Теги

Похожие вопросы