Linux exec bash file

Использование команды Exec в сценарии Bash

При создании сценариев Bash мы можем захотеть перенаправить вывод всех операторов echo в файл журнала без явного указания оператора перенаправления и имени файла журнала после каждого оператора echo. Команда Bash exec — это мощная встроенная утилита, которую можно использовать для этой цели. В этом руководстве мы рассмотрим, как можно использовать команду exec для добавления протоколирования ошибок и вывода в сценарии оболочки. Мы также рассмотрим другие способы использования этой команды в сценариях командного интерпретатора.

Основы

При выполнении любой команды в оболочке Bash по умолчанию создается подоболочка, и порождается новый дочерний процесс (forked) для выполнения команды. Однако при использовании команды exec команда, следующая за exec, заменяет текущую оболочку. Это означает, что под-оболочка не создается, а текущий процесс заменяется этой новой командой.

Давайте проведем эксперимент, чтобы лучше понять это:

pstree -p init(1)─┬─init(52)───bash(53) ├─init(78)───bash(79)───pstree(108) └─(7) echo $$ 79 exec sleep 300

Мы проверили PID текущей оболочки с помощью команд echo $$ и pstree, а затем выполнили sleep на 300 секунд с помощью exec. Давайте теперь переключимся на другой терминал, чтобы проверить список процессов:

ps -aef | grep $USER user1 53 52 0 23:37 tty2 00:00:00 -bash user1 79 78 0 23:39 tty1 00:00:00 sleep 300 user1 111 53 0 23:40 tty2 00:00:00 ps -aef user1 112 53 0 23:40 tty2 00:00:00 grep --color=auto

Как мы видим, PID 79, который изначально был назначен на Bash, теперь назначен на команду sleep.

Мы также наблюдаем, что после завершения 300-секундного сна сессия (терминал), имевшая PID 79, вышла, поскольку оболочка была заменена командой exec, и ее выполнение завершилось.

Замена процесса с помощью команды exec

Замена существующего процесса другой командой может быть мощным инструментом. Давайте рассмотрим эту идею на других примерах.

Профиль входа пользователя

Предположим, что Bash не является оболочкой по умолчанию на нашем Linux. Интересно, что с помощью команды exec мы можем заменить оболочку по умолчанию в памяти на оболочку Bash, добавив ее в профиль входа пользователя:

Бывают сценарии, когда мы хотим добавить определенную программу или меню в профиль входа пользователя (.bashrc или .bash_profile), и в таких случаях мы можем предотвратить доступ пользователя к интерпретатору Bash после завершения программы независимо от статуса завершения:

Вызовы программ внутри сценариев

Мы можем вызывать скрипты или другие программы внутри скрипта с помощью exec, чтобы перекрыть существующий процесс в памяти. Это экономит количество создаваемых процессов и, следовательно, системные ресурсы. Такая реализация особенно полезна в случаях, когда мы не хотим возвращаться в основной скрипт после выполнения подскрипта или программы:

#! /bin/bash while true do echo "1. Статистика диска " echo "2. Отправить отчет " read Input case "$Input" in 1) exec df -kh ;; 2) exec /home/SendReport.sh ;; esac done

В этом простом сценарии, управляемом пользовательским вводом, мы выполнили команду df и сценарий с помощью exec в различных пунктах меню.

Читайте также:  Сколько памяти занял процесс linux

Дескрипторы файлов и протоколирование в сценариях Shell с помощью команды exec

Команда exec — это мощный инструмент для манипулирования дескрипторами файлов (FD), создания вывода и протоколирования ошибок в сценариях с минимальными изменениями. В Linux по умолчанию файловым дескриптором:

  • 0 — является stdin (стандартный ввод)
  • 1 — stdout (стандартный вывод)
  • 2 — stderr (стандартная ошибка).

Ведение журнала в сценариях

Мы можем динамически открывать, закрывать и копировать stdout для выполнения операций протоколирования. Давайте перенаправим stdout (FD 1) в файл журнала:

#! /bin/bash script_log="/tmp/log_`date+%F`.log" exec 1>>$script_log echo "Это будет записано в лог-файл, а не в терминал. ". echo "Это тоже. "

Мы проверили, как мы можем записывать стандартный вывод в файлы, теперь давайте проверим, как мы можем также записывать стандартную ошибку в тот же файл:

#! /bin/bash script_log="/home/shubh/log_`date+%F`.log" exec 1>>$script_log exec 2>&1 date echo "Вышеприведенная команда неверна, ошибка будет записана в лог-файл" date echo "Вывод правильной команды date также будет записан в лог-файл, включая эти заявления echo"

Здесь мы скопировали stderr (2) в stdout (1), а stdout уже был изменен для записи в файл журнала.

Изменение Stdin для чтения из файла

Давайте создадим пример входного файла:

Пример файла

Теперь запустим пример для чтения из созданного нами файла:

Пример вывода

Изменение файловых дескрипторов и восстановление значений по умолчанию

Мы также можем открывать и закрывать новые файловые дескрипторы для чтения и записи из файлов. Для демонстрации этого воспользуемся тем же входным файлом, что и в предыдущем разделе:

#! /bin/bash exec 3< input.csv read -u 3 row1 echo $row1 exec 3&1 exec > out.txt echo "Выходные данные будут записаны в файл out.txt" exec 4>&-

Здесь мы сначала открыли входной файл на FD 3, прочитали из файла и вывели его содержимое на терминал (по умолчанию на stdout). Наконец, мы использовали &- для закрытия FD 3. Когда этот сценарий выполняется, он выводит следующие данные:

вывод скрипта

Кроме того, скрипт создает выходной файл out.txt:

Вывод будет зарегистрирован в файле out.txt

cat out.txt

Обратите внимание, что вывод скрипта содержит только первый оператор echo. Интересно, что после первого оператора echo мы скопировали stdout на FD 4 и перенаправили его в другой файл. Позже, в последней строке, мы восстановили доступ к stdout, закрыв FD 4.

Запуск сценариев в чистой среде

Мы можем сбросить все переменные окружения для чистого запуска с помощью опции -c:

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

Использование с командой Find

Опцию exec можно использовать для выполнения таких операций, как grep, cat, mv, cp, rm и многих других над файлами, найденными командой find. Давайте воспользуемся примером из нашей статьи о команде find, чтобы найти все файлы .java, содержащие слово «interface» в каталоге src:

find src -name "*.java" -type f -exec grep -l interface <> \;

Здесь мы указали опцию -type f, чтобы найти только обычные файлы. Затем мы использовали опцию -exec для выполнения команды grep в списке файлов, возвращенных командой find. Обратите внимание, что точка с запятой в конце заставляет команду grep выполняться для каждого файла по очереди, поскольку <> заменяется именем текущего файла. Обратите внимание, что обратная косая черта необходима для того, чтобы точка с запятой не интерпретировалась оболочкой.

Читайте также:  Ora 27102 linux cannot allocate memory

Заключение

В этом руководстве мы рассмотрели различные варианты использования встроенной в Bash команды exec в сценариях оболочки.

Проще говоря, это мощный инструмент для замены процессов. В частности, ее использование с дескрипторами файлов в сценариях делает ее одним из самых мощных инструментов для гибкого протоколирования сценариев.

Похожие записи:

Источник

Команда exec в Linux

В Linux команда exec , выполняющая команды из самого Bash, является мощным инструментом замены процессов, гибкого протоколирования сценариев.

Примеры использования команды exec в Linux

Если команда exec выполнена успешно, она не возвращается к вызывающему процессу.

Синтаксис

exec [опции] [команда [аргументы]] [перенаправление]

Опции

-c Выполнение команды в чистой среде -l Передача тире — в качестве нулевого аргумента -a [имя] Передача имя в качестве нулевого аргумента

Команда exec не создает новый процесс. Когда мы запускаем утилиту из терминала, текущий терминальный процесс заменяется командой, которая предоставляется в качестве аргумента.

Использование команды exec в Linux

Базовое использование (замена процесса)

Для замены процесса открывается терминал и перечисляются запущенные процессы:

oleg@mobile:~:$ ps PID TTY TIME CMD 187005 pts/0 00:00:00 bash 190994 pts/0 00:00:00 ps oleg@mobile:~:$ 

Вывод показывает текущую запущенную оболочку Bash и команду ps . Оболочка Bash имеет уникальный PID.

Для подтверждения можно проверить идентификатор текущего процесса:

oleg@mobile:~:$ echo $$ 187005 oleg@mobile:~:$ 

PID совпадает с выводом команды ps , указывая на то, что это текущий процесс Bash.

Утилита с дополнительной командой в качестве аргумента

В этом режиме exec пытается выполнить аргумент как команду, передавая оставшиеся аргументы, если они есть, этой команде и управляя перенаправлениями, если таковые имеются.

oleg@mobile:~:$ bash non-network local connections being added to access control list oleg@mobile:~:$ exec ls abc.txt backgrounds Desktop Documents store www Документы Музыка Apps bin Directory Downloads tmp Yandex.Disk Загрузки Общедоступные aur ChestitaBabaMarta.jpg docs mailbox webprojects Видео Изображения Шаблоны oleg@mobile:~:$

Утилита exec ищет путь, указанный в переменной $PATH с необходимой исполняемой командой. Если команда не найдена, утилита, а также оболочка завершают работу с ошибкой.

Замена текущего сеанса оболочки

Проверяем текущий PID оболочки:

oleg@mobile:~:$ echo $$ 179575 oleg@mobile:~:$ 

Используем утилиту для переключения в оболочку Bourne:

oleg@mobile:~:$ exec sh oleg@mobile:~:$ 

На другой вкладке проверяем PID процесса Bourne Shell:

oleg@mobile:~:$ ops -ae | grep "\bsh\b"| grep "\bsh\b" 179575 pts/0 00:00:00 sh oleg@mobile:~:$ 

Выход из Bourne Shell завершит сеанс терминала.

Запуск скриптов в чистой среде

Для сброса всех переменных окружения и чистого запуска используется опция -c :

oleg@mobile:~:$ exec -c printenv

В связи с тем, что команда printenv перечисляет переменные окружения, то при передаче её в качестве аргумента вывод будет пустым.

Выполнение утилиты с командой поиска

Утилиту exec можно использовать для выполнения операций: grep , cat , mv , cp , rm и других над файлами, найденными командой find .

Читайте также:  Linux check if it is 64 bit

Для примера найдём все файлы * , содержащие слово iwd в каталоге ~/webprojects/linuxcookbook.ru/artiles :

oleg@mobile:~:$ find ~/webprojects/linuxcookbook.ru/articles -name "*" -type f -exec grep -l iwd <> \; /home/oleg/webprojects/linuxcookbook.ru/articles/utilita-iwctl-arch-linux /home/oleg/webprojects/linuxcookbook.ru/articles/RCS/utilita-iwctl-arch-linux,v oleg@mobile:~:$ 

Здесь для поиска обычных текстовых файлов была указана опция -type f . Затем мы использовали опцию -exec для выполнения команды grep в списке файлов, возвращённых командой find .

Точка с запятой в конце ; заставляет команду grep исполняться для каждого файла по очереди, поскольку <> заменяется именем текущего файла. Обратите внимание, что обратный слэш необходим для того, чтобы точка с запятой не интерпретировалась оболочкой.

Заключение

В этой статье были рассмотрены основные варианты использования встроенной в Bash команды exec . Она может быть вам очень полезна.

Источник

What does an «exec» command do?

I don’t understand the bash command exec . I have seen it used inside scripts to redirect all output to a file (as seen in this). But I don’t understand how it works or what it does in general. I have read the man pages but I don’t understand them.

But actually your script uses exec in a special way which can be explained much more simply, I will write an answer.

4 Answers 4

exec [-cl] [-a name] [command [arguments]] If command is specified, it replaces the shell. No new process is created. The arguments become the arguments to command. If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what login(1) does. The -c option causes command to be executed with an empty environment. If -a is supplied, the shell passes name as the zeroth argument to the executed command. If command cannot be executed for some reason, a non-interactive shell exits, unless the execfail shell option is enabled. In that case, it returns failure. An interactive shell returns failure if the file cannot be executed. If command is not specified, any redirections take effect in the current shell, and the return status is 0. If there is a redirection error, the return status is 1. 

The last two lines are what is important: If you run exec by itself, without a command, it will simply make the redirections apply to the current shell. You probably know that when you run command > file , the output of command is written to file instead of to your terminal (this is called a redirection). If you run exec > file instead, then the redirection applies to the entire shell: Any output produced by the shell is written to file instead of to your terminal. For example here

bash-3.2$ bash bash-3.2$ exec > file bash-3.2$ date bash-3.2$ exit bash-3.2$ cat file Thu 18 Sep 2014 23:56:25 CEST 

I first start a new bash shell. Then, in this new shell I run exec > file , so that all output is redirected to file . Indeed, after that I run date but I get no output, because the output is redirected to file . Then I exit my shell (so that the redirection no longer applies) and I see that file indeed contains the output of the date command I ran earlier.

Источник

Оцените статью
Adblock
detector