- команда exec в Linux с примерами
- Bash exec builtin command
- Description
- Syntax
- Options and arguments
- Description
- Examples
- Related commands
- Команда exec
- Что означает «exec» перед командой bash?
- Bash-скрипты, часть 4: ввод и вывод
- Стандартные дескрипторы файлов
- STDIN
- STDOUT
- STDERR
- ▍Перенаправление потока ошибок
- ▍Перенаправление потоков ошибок и вывода
- Перенаправление вывода в скриптах
- ▍Временное перенаправление вывода
- ▍Постоянное перенаправление вывода
- Перенаправление ввода в скриптах
- Создание собственного перенаправления вывода
- Создание дескрипторов файлов для ввода данных
- Закрытие дескрипторов файлов
- Получение сведений об открытых дескрипторах
- Подавление вывода
- Итоги
команда exec в Linux с примерами
Команда exec в Linux используется для выполнения команды из самого bash. Эта команда не создает новый процесс, она просто заменяет bash командой, которая должна быть выполнена. Если команда exec успешна, она не возвращается к вызывающему процессу.
Синтаксис:
Параметры:
- c: используется для выполнения команды с пустой средой.
- имя: используется для передачи имени в качестве нулевого аргумента команды.
- l: используется для передачи тире в качестве нулевого аргумента команды.
Примечание: команда exec не создает новый процесс. Когда мы запускаем команду exec из терминала, текущий процесс терминала заменяется командой, предоставленной в качестве аргумента для команды exec.
Команда exec может использоваться в двух режимах:
- Exec с командой в качестве аргумента: В первом режиме exec пытается выполнить ее как команду, передавая оставшиеся аргументы, если таковые имеются, этой команде и управляя перенаправлениями, если они есть.
Пример 1:
Пример 2:
Команда exec ищет путь, указанный в переменной $ PATH, чтобы найти команду для выполнения. Если команда не найдена, команда exec, а также оболочка завершается с ошибкой.
Exec без команды: если команда не указана, перенаправления могут использоваться для изменения текущей среды оболочки. Это полезно, так как позволяет нам изменять файловые дескрипторы оболочки по нашему желанию. Процесс продолжается даже после выполнения команды exec, в отличие от предыдущего случая, но теперь стандартный ввод, вывод и ошибка изменяются в соответствии с перенаправлениями.
Пример:
Здесь команда exec изменяет стандарт из оболочки на файл tmp, и поэтому все команды, выполняемые после команды exec, записывают свои результаты в этот файл. Это один из самых распространенных способов использования exec без каких-либо команд.
Источник
Bash exec builtin command
On Unix-like operating systems, exec is a builtin command of the Bash shell. It allows you to execute a command that completely replaces the current process. The current shell process is destroyed, and entirely replaced by the command you specify.
Description
exec is a critical function of any Unix-like operating system. Traditionally, the only way to create a new process in Unix is to fork it. The fork system call makes a copy of the forking program. The copy then uses exec to execute the child process in its memory space.
Syntax
Options and arguments
The exec builtin command takes the following options and arguments:
-a name | Pass the string name as the zeroth argument to command. This option is available in bash versions 4.2 and above. When used, it will execute command, and set the special shell variable $0 to the value name, instead of command. For more information, see bash special parameter 0. |
-c | Execute command in an empty environment. |
-l | Insert a dash at the beginning of the zeroth argument. This can start a login shell via exec. For more information about login shells, and bash’s requirements about how they may be invoked, see shell invocation in bash. |
command | The command to be executed. If you do not specify a command, exec can still provide redirection. |
arguments | The arguments for the command you’d like to execute. |
redirection | Any redirection for the command. If no command is specified, redirection applies to the current shell. |
Description
exec is useful when you want to run a command, but you don’t want a bash shell to be the parent process. When you exec a command, it replaces bash entirely — no new process is forked, no new PID is created, and all memory controlled by bash is destroyed and overwritten. This can be useful if, for instance, you want to give a user restricted access to a certain command. If the command exits because of an error, the user is not returned to the privileged shell that executed it.
exec may also be used without any command, to redirect all output of the current shell to a file. For more information about redirection, see redirection in the bash shell.
Examples
Replace the current bash shell with rbash, the restricted bash login shell. Because the original bash shell is destroyed, the user is not returned to a privileged bash shell when rbash exits.
Redirect all output to the file output.txt for the current shell process. Redirections are a special case, and exec does not destroy the current shell process, but bash will no longer print output to the screen, writing it to the file instead. (This technique is much more useful in scripts — if the above command is executed in a script, all script output will be written to output.txt.)
Open myinfile.txt for reading (» «) on file descriptor 4.
Close («&-«) the open read descriptor (» «) number 4.
Open myfile.txt for reading and writing («<>«) as file descriptor 5.
Close open read/write descriptor 5.
Open myappendfile.txt for appending («>>«) as file descriptor 6.
Open out.txt for writing. A new file descriptor number, chosen automatically, is assigned to the variable myfd.
Echo the text «Text» and redirect the output to the file (in this case, out.txt) described by the write descriptor («>«) whose number is obtained by dereferencing («&«) the value of the variable («$«) named myfd.
Related commands
read — Read a line of input, and split it into words.
Источник
Команда exec
Запуск сценария из командной строки приводит к запуску новой оболочки, которая и будет выполнять список команд, содержащихся в файле сценария. Другими словами, любой сценарий (или программа) запускается как дочерний процесс родительской командной оболочки. Однако, программа, выполняемая по команде exec , заменяет текущую программу, и поэтому в системе остается на один выполняемый процесс меньше.
Действие, когда какая либо команда или сама командная оболочка инициирует (порождает) новый подпроцесс, чтобы выполнить какую либо работу, называется ветвлением (forking) процесса. Новый процесс называется «дочерним» (или «потомком»), а породивший его процесс — «родительским» (или «предком»). В результате и потомок и предок продолжают исполняться одновременно — параллельно друг другу.
Общая форма команды exec :
Пусть нам нужно настроить среду для выполнения определенной задачи, например, для работы с базой данных: заменить приглашение в переменной PS1 на DataBase , добавить в переменную PATH каталог bin базы данных, изменить переменную CDPATH (чтобы было удобнее использовать команду cd ) и т.п.
С помощью команды exec можно переназначить стандартный ввод ( stdin ) и стандартный вывод ( stdout ). Например, переназначим стандартный ввод:
Любые последующие команды, читающие данные со стандартного ввода, будут читать их из файла inputFile.txt . Пример использования в сценарии:
Переадресация стандартного вывода выполняется аналогично:
Следует, однако, иметь в виду, что в обоих примерах команда exec применялась не для запуска новой программы на выполнение, а лишь для переназначения стандартного ввода или вывода.
Чтобы переназначить стандартный ввод обратно на терминал, достаточно ввести команду:
Аналогичным образом переназначается и стандартный вывод:
Источник
Что означает «exec» перед командой bash?
Я читал про перенаправление потоков с пом. exec, вроде-бы понимаю смысл, вроде-бы понимаю как это работает, но видимо только методично. Например в bash скриптах я встречал использование echo просто так:
своими словами если, это значит что запущенный процесс подменит собой шелл.
ты запускаешь эмулятор терминала, эмулятор терминала выполняет bash — эту самую командную строку.
запуская программу через exec ты передаёшь управление этой программе, вместо bash, а bash закрывается. то есть, запускаешь exec top, теперь в эмуляторе терминала запущен не: bash — top, а просто top. и закрывая top, эмулятору терминала больше нечего выполнять, он закономерно закрывается.
ок, допустим, это я понял. Действительно, если запустить интерпритатор python без exec, то выйдя с него возвращаешся в bash, а если с ним то нафиг из терминала. Зачем можно выполнять echo с exec? Какой-то абсурд. И почему тогда apt-get update не выполнился и потом закрылся? или хотябы, если терминал ему не нужен, обновил бы пакеты без терминала, но нет.
кажись понял.
походу в скрипте bash, если встречается exec echo, то сразу после его выполнения программа прерывается. Получается exec в скриптах bash только для последнего действия, которое не должно возвращать никакого значения в программу этого самого скрипта.
А почему exec apt-get update не обновил пакеты я так и не понял.
какой-то зашквар
ладно, вопрос закрыт
А почему exec apt-get update не обновил пакеты я так и не понял.
Команду от рута выполнял?
apt-get update не обновляет пакеты, а только «базу данных» пакетов.
apt-get upgrade — уже обновляет пакеты.
пардон, я это и имел введу. В любом случае, когда я выполнил apt-get update через некоторое время, понял что база данных пакетов давно не обновлялась
Помимо всего прочего echo text — это обращение ко встроенной в Баш функции, а exec echo text — ко внешней утилите echo (да, такая есть, /bin/echo , как правило).
И я решительно не понимаю, зачем это может быть нужно. Или вы это в качестве примера придумали, а вовсе не видели такое где-либо?
И я решительно не понимаю, зачем это может быть нужно. Или вы это в качестве примера придумали, а вовсе не видели такое где-либо?
Я такого тоже не встречал, но имхо можно использовать для выхода из программы по условию, с сообщением в консоль.
Я себе скрипт для автозагрузки окружения говнякал, например, примерно такой:
увидел использование exec в скрипте запуска lightstreamer и полез в поиск. Спасибо за тред.
Источник
Bash-скрипты, часть 4: ввод и вывод
В прошлый раз, в третьей части этой серии материалов по bash-скриптам, мы говорили о параметрах командной строки и ключах. Наша сегодняшняя тема — ввод, вывод, и всё, что с этим связано.
Вы уже знакомы с двумя методами работы с тем, что выводят сценарии командной строки:
- Отображение выводимых данных на экране.
- Перенаправление вывода в файл.
Иногда что-то надо показать на экране, а что-то — записать в файл, поэтому нужно разобраться с тем, как в Linux обрабатывается ввод и вывод, а значит — научиться отправлять результаты работы сценариев туда, куда нужно. Начнём с разговора о стандартных дескрипторах файлов.
Стандартные дескрипторы файлов
Всё в Linux — это файлы, в том числе — ввод и вывод. Операционная система идентифицирует файлы с использованием дескрипторов.
Каждому процессу позволено иметь до девяти открытых дескрипторов файлов. Оболочка bash резервирует первые три дескриптора с идентификаторами 0, 1 и 2. Вот что они означают.
- 0 , STDIN — стандартный поток ввода.
- 1 , STDOUT — стандартный поток вывода.
- 2 , STDERR — стандартный поток ошибок.
Эти три специальных дескриптора обрабатывают ввод и вывод данных в сценарии.
Вам нужно как следует разобраться в стандартных потоках. Их можно сравнить с фундаментом, на котором строится взаимодействие скриптов с внешним миром. Рассмотрим подробности о них.
STDIN
STDIN — это стандартный поток ввода оболочки. Для терминала стандартный ввод — это клавиатура. Когда в сценариях используют символ перенаправления ввода — , Linux заменяет дескриптор файла стандартного ввода на тот, который указан в команде. Система читает файл и обрабатывает данные так, будто они введены с клавиатуры.
Многие команды bash принимают ввод из STDIN , если в командной строке не указан файл, из которого надо брать данные. Например, это справедливо для команды cat .
Когда вы вводите команду cat в командной строке, не задавая параметров, она принимает ввод из STDIN . После того, как вы вводите очередную строку, cat просто выводит её на экран.
STDOUT
STDOUT — стандартный поток вывода оболочки. По умолчанию это — экран. Большинство bash-команд выводят данные в STDOUT , что приводит к их появлению в консоли. Данные можно перенаправить в файл, присоединяя их к его содержимому, для этого служит команда >> .
Итак, у нас есть некий файл с данными, к которому мы можем добавить другие данные с помощью этой команды:
То, что выведет pwd , будет добавлено к файлу myfile , при этом уже имеющиеся в нём данные никуда не денутся.
Перенаправление вывода команды в файл
Пока всё хорошо, но что если попытаться выполнить что-то вроде показанного ниже, обратившись к несуществующему файлу xfile , задумывая всё это для того, чтобы в файл myfile попало сообщение об ошибке.
После выполнения этой команды мы увидим сообщения об ошибках на экране.
Попытка обращения к несуществующему файлу
При попытке обращения к несуществующему файлу генерируется ошибка, но оболочка не перенаправила сообщения об ошибках в файл, выведя их на экран. Но мы-то хотели, чтобы сообщения об ошибках попали в файл. Что делать? Ответ прост — воспользоваться третьим стандартным дескриптором.
STDERR
STDERR представляет собой стандартный поток ошибок оболочки. По умолчанию этот дескриптор указывает на то же самое, на что указывает STDOUT , именно поэтому при возникновении ошибки мы видим сообщение на экране.
Итак, предположим, что надо перенаправить сообщения об ошибках, скажем, в лог-файл, или куда-нибудь ещё, вместо того, чтобы выводить их на экран.
▍Перенаправление потока ошибок
Как вы уже знаете, дескриптор файла STDERR — 2. Мы можем перенаправить ошибки, разместив этот дескриптор перед командой перенаправления:
Сообщение об ошибке теперь попадёт в файл myfile .
Перенаправление сообщения об ошибке в файл
▍Перенаправление потоков ошибок и вывода
При написании сценариев командной строки может возникнуть ситуация, когда нужно организовать и перенаправление сообщений об ошибках, и перенаправление стандартного вывода. Для того, чтобы этого добиться, нужно использовать команды перенаправления для соответствующих дескрипторов с указанием файлов, куда должны попадать ошибки и стандартный вывод:
Перенаправление ошибок и стандартного вывода
Оболочка перенаправит то, что команда ls обычно отправляет в STDOUT , в файл correctcontent благодаря конструкции 1> . Сообщения об ошибках, которые попали бы в STDERR , оказываются в файле errorcontent из-за команды перенаправления 2> .
Если надо, и STDERR , и STDOUT можно перенаправить в один и тот же файл, воспользовавшись командой &> :
Перенаправление STDERR и STDOUT в один и тот же файл
После выполнения команды то, что предназначено для STDERR и STDOUT , оказывается в файле content .
Перенаправление вывода в скриптах
Существует два метода перенаправления вывода в сценариях командной строки:
- Временное перенаправление, или перенаправление вывода одной строки.
- Постоянное перенаправление, или перенаправление всего вывода в скрипте либо в какой-то его части.
▍Временное перенаправление вывода
В скрипте можно перенаправить вывод отдельной строки в STDERR . Для того, чтобы это сделать, достаточно использовать команду перенаправления, указав дескриптор STDERR , при этом перед номером дескриптора надо поставить символ амперсанда ( & ):
Если запустить скрипт, обе строки попадут на экран, так как, как вы уже знаете, по умолчанию ошибки выводятся туда же, куда и обычные данные.
Запустим скрипт так, чтобы вывод STDERR попадал в файл.
Как видно, теперь обычный вывод делается в консоль, а сообщения об ошибках попадают в файл.
Сообщения об ошибках записываются в файл
▍Постоянное перенаправление вывода
Если в скрипте нужно перенаправлять много выводимых на экран данных, добавлять соответствующую команду к каждому вызову echo неудобно. Вместо этого можно задать перенаправление вывода в определённый дескриптор на время выполнения скрипта, воспользовавшись командой exec :
Перенаправление всего вывода в файл
Если просмотреть файл, указанный в команде перенаправления вывода, окажется, что всё, что выводилось командами echo , попало в этот файл.
Команду exec можно использовать не только в начале скрипта, но и в других местах:
Вот что получится после запуска скрипта и просмотра файлов, в которые мы перенаправляли вывод.
Перенаправление вывода в разные файлы
Сначала команда exec задаёт перенаправление вывода из STDERR в файл myerror . Затем вывод нескольких команд echo отправляется в STDOUT и выводится на экран. После этого команда exec задаёт отправку того, что попадает в STDOUT , в файл myfile , и, наконец, мы пользуемся командой перенаправления в STDERR в команде echo , что приводит к записи соответствующей строки в файл myerror.
Освоив это, вы сможете перенаправлять вывод туда, куда нужно. Теперь поговорим о перенаправлении ввода.
Перенаправление ввода в скриптах
Для перенаправления ввода можно воспользоваться той же методикой, которую мы применяли для перенаправления вывода. Например, команда exec позволяет сделать источником данных для STDIN какой-нибудь файл:
Эта команда указывает оболочке на то, что источником вводимых данных должен стать файл myfile , а не обычный STDIN . Посмотрим на перенаправление ввода в действии:
Вот что появится на экране после запуска скрипта.
В одном из предыдущих материалов вы узнали о том, как использовать команду read для чтения данных, вводимых пользователем с клавиатуры. Если перенаправить ввод, сделав источником данных файл, то команда read , при попытке прочитать данные из STDIN , будет читать их из файла, а не с клавиатуры.
Некоторые администраторы Linux используют этот подход для чтения и последующей обработки лог-файлов.
Создание собственного перенаправления вывода
Перенаправляя ввод и вывод в сценариях, вы не ограничены тремя стандартными дескрипторами файлов. Как уже говорилось, можно иметь до девяти открытых дескрипторов. Остальные шесть, с номерами от 3 до 8, можно использовать для перенаправления ввода или вывода. Любой из них можно назначить файлу и использовать в коде скрипта.
Назначить дескриптор для вывода данных можно, используя команду exec :
После запуска скрипта часть вывода попадёт на экран, часть — в файл с дескриптором 3 .
Перенаправление вывода, используя собственный дескриптор
Создание дескрипторов файлов для ввода данных
Перенаправить ввод в скрипте можно точно так же, как и вывод. Сохраните STDIN в другом дескрипторе, прежде чем перенаправлять ввод данных.
После окончания чтения файла можно восстановить STDIN и пользоваться им как обычно:
В этом примере дескриптор файла 6 использовался для хранения ссылки на STDIN . Затем было сделано перенаправление ввода, источником данных для STDIN стал файл. После этого входные данные для команды read поступали из перенаправленного STDIN , то есть из файла.
После чтения файла мы возвращаем STDIN в исходное состояние, перенаправляя его в дескриптор 6 . Теперь, для того, чтобы проверить, что всё работает правильно, скрипт задаёт пользователю вопрос, ожидает ввода с клавиатуры и обрабатывает то, что введено.
Закрытие дескрипторов файлов
Оболочка автоматически закрывает дескрипторы файлов после завершения работы скрипта. Однако, в некоторых случаях нужно закрывать дескрипторы вручную, до того, как скрипт закончит работу. Для того, чтобы закрыть дескриптор, его нужно перенаправить в &- . Выглядит это так:
После исполнения скрипта мы получим сообщение об ошибке.
Попытка обращения к закрытому дескриптору файла
Всё дело в том, что мы попытались обратиться к несуществующему дескриптору.
Будьте внимательны, закрывая дескрипторы файлов в сценариях. Если вы отправляли данные в файл, потом закрыли дескриптор, потом — открыли снова, оболочка заменит существующий файл новым. То есть всё то, что было записано в этот файл ранее, будет утеряно.
Получение сведений об открытых дескрипторах
Для того, чтобы получить список всех открытых в Linux дескрипторов, можно воспользоваться командой lsof . Во многих дистрибутивах, вроде Fedora, утилита lsof находится в /usr/sbin . Эта команда весьма полезна, так как она выводит сведения о каждом дескрипторе, открытом в системе. Сюда входит и то, что открыли процессы, выполняемые в фоне, и то, что открыто пользователями, вошедшими в систему.
У этой команды есть множество ключей, рассмотрим самые важные.
- -p Позволяет указать ID процесса.
- -d Позволяет указать номер дескриптора, о котором надо получить сведения.
Для того, чтобы узнать PID текущего процесса, можно использовать специальную переменную окружения $$ , в которую оболочка записывает текущий PID .
Ключ -a используется для выполнения операции логического И над результатами, возвращёнными благодаря использованию двух других ключей:
Вывод сведений об открытых дескрипторах
Тип файлов, связанных с STDIN , STDOUT и STDERR — CHR (character mode, символьный режим). Так как все они указывают на терминал, имя файла соответствует имени устройства, назначенного терминалу. Все три стандартных файла доступны и для чтения, и для записи.
Посмотрим на вызов команды lsof из скрипта, в котором открыты, в дополнение к стандартным, другие дескрипторы:
Вот что получится, если этот скрипт запустить.
Просмотр дескрипторов файлов, открытых скриптом
Скрипт открыл два дескриптора для вывода ( 3 и 6 ) и один — для ввода ( 7 ). Тут же показаны и пути к файлам, использованных для настройки дескрипторов.
Подавление вывода
Иногда надо сделать так, чтобы команды в скрипте, который, например, может исполняться как фоновый процесс, ничего не выводили на экран. Для этого можно перенаправить вывод в /dev/null . Это — что-то вроде «чёрной дыры».
Вот, например, как подавить вывод сообщений об ошибках:
Тот же подход используется, если, например, надо очистить файл, не удаляя его:
Итоги
Сегодня вы узнали о том, как в сценариях командной строки работают ввод и вывод. Теперь вы умеете обращаться с дескрипторами файлов, создавать, просматривать и закрывать их, знаете о перенаправлении потоков ввода, вывода и ошибок. Всё это очень важно в деле разработки bash-скриптов.
В следующий раз поговорим о сигналах Linux, о том, как обрабатывать их в сценариях, о запуске заданий по расписанию и о фоновых задачах.
Уважаемые читатели! В этом материале даны основы работы с потоками ввода, вывода и ошибок. Уверены, среди вас есть профессионалы, которые могут рассказать обо всём этом то, что приходит лишь с опытом. Если так — передаём слово вам.
Источник