Использование команды exec в сценариях оболочки Bash [4 примера]
Команда exec в сценариях оболочки очень полезна для ведения журналов, чтения файлов и запуска команд путем замены текущего процесса.
Встроенная команда оболочки exec используется для выполнения команд в сценариях оболочки.
Ждать! Разве сценарии оболочки уже не выполняют команды Linux? Они делают. Но exec запускает команды Linux без запуска нового процесса. Он заменяет процесс оболочки указанной командой.
Кажется сложным? Позвольте мне привести вам несколько примеров использования команды exec в сценариях оболочки:
Замена процесса
-
Вход в сценарий оболочки
Измените стандартный ввод для чтения файла
Изменить дескрипторы файлов
Итак, начнем с первого.
1. Используйте команду exec для замены процесса в сценарии оболочки.
Замена процесса — одна из наиболее известных реализаций exec в сценарии оболочки.
Итак, здесь я буду использовать простой сценарий, который покажет, как можно использовать команду exec в сценарии для замены текущего процесса оболочки.
Сначала используйте следующую команду, чтобы использовать nano для создания и редактирования нового сценария:
nano process_replacement.sh
И вставьте следующее:
#!/bin/bash
echo "Before exec: This is the original script"
exec ls -l
echo "After exec: This line will not be executed"
После этого сохраните изменения и выйдите из текстового редактора nano.
Теперь позвольте мне объяснить, что будет делать этот скрипт.
Вот три командных оператора. Сначала будет напечатан основной текст с указанием исходного сценария, который подлежит замене.
Второй оператор включает в себя использование команды exec с командой ls для вывода списка содержимого текущего рабочего каталога и также заменит предыдущий процесс!
Теперь третий оператор не будет выполнен, поскольку ранее процесс был заменен на exec, и не было дополнительных аргументов для поддержки выполнения третьего командного оператора.
Проще говоря, процесс будет заменен вторым аргументом команды, а третья команда выполняться не будет.
И вот результат, если вы выполните показанный скрипт:
И, как вы можете видеть, здесь показан третий оператор команды, который должен был вывести «После выполнения: эта строка не будет выполнена».
Это кажется не очень практичным? Вот еще один пример.
2. Используйте команду exec в сценариях оболочки для ведения журнала.
Еще одна интересная и простая реализация exec: вы можете перенаправить вывод в файл.
Здесь я буду использовать три аргумента: два для стандартного вывода и один для стандартной ошибки.
Вот сценарий:
#!/bin/bash
LOG_FILE="script.log"
# Redirect stdout and stderr to the log file
exec &> "$LOG_FILE"
# Start logging
echo "Script started at $(date)"
# Perform some operations
echo "Performing operation 1 (stdout)..."
ls -l /path/to/directory
echo "Performing operation 2 (stderr)..."
grep "search term" /path/to/nonexistentfile
echo "Performing operation 3 (stdout)..."
cat /path/to/file
# Log completion
echo "Script completed at $(date)"
Я создал пустой файл с именем script.log
в том же каталоге, где находится приведенный выше сценарий, для хранения журналов.
Здесь команда exec перенаправит вывод в файл журнала, включая время запуска и завершения.
Когда я запустил скрипт, файл, содержащий файл журнала, выглядел так:
3. Измените стандартный ввод на чтение файлов с помощью exec.
Это может быть очень полезно при выполнении определенных операций над файлом.
Здесь я буду использовать простой текстовый файл с именем Hello.txt
, который содержит несколько случайных текстовых строк:
Ubuntu, openSUSE, Arch, Debian, Fedora
+ - / *
2 4 6 1
4 6 1 2
А вот скрипт, который будет читать из файла и выводить содержимое на стандартный вывод:
#!/bin/bash
INPUT_FILE="Hello.txt"
# Redirect stdin to read from a file
exec < "$INPUT_FILE"
# Read the entire file as a single input
content=$(cat)
# Process the input
echo "Read: $content"
Теперь позвольте мне объяснить сценарий.
INPUT_FILE
указывает, из какого файла следует читать.exec < "$INPUT_FILE"
— перенаправление на чтение из указанного файла.content=$ (cat)
прочитает весь текстовый файл и назначит его переменнойcontent
.echo "Read: $content"
выведет значение переменнойcontent
.
И если выполнить скрипт, то результат будет выглядеть так:
4. Измените дескрипторы файлов с помощью exec в сценарии оболочки (дополнительно)
В Linux существует три стандартных файловых дескриптора:
Стандартный ввод (stdin — файловый дескриптор 0)
Стандартный вывод (stdout — файловый дескриптор 1)
Стандартная ошибка (stderr — файловый дескриптор 2)
А с помощью команды exec можно изменить дескрипторы. Например, вы можете использовать любое число для использования предпочтительного потока данных, например, используя 3 для стандартного ввода.
Позвольте мне сначала поделиться сценарием, а затем объяснить, как он работает:
#!/bin/bash
# Open a file for writing
exec 3> output.txt
# Redirect stdout to file descriptor 3
exec 1>&3
# Print some output
echo "This is a test message"
# Close the file descriptor
exec 3>&-
Здесь я открыл файл output.txt
и назначил файловый дескриптор 3, что означает, что все, отправленное в файловый дескриптор 3, будет записано в файл.
Используя exec 1>&3
, я перенаправил стандартный вывод (1) в файловый дескриптор 3, что означает, что все, записанное в стандартный вывод, будет отправлено в файловый дескриптор 3 (в файл output.txt в мое дело).
Оператор echo выводит текст на стандартный вывод (который будет отправлен в файл, поскольку мы ранее изменили дескриптор файла).
А exec 3>&-
убивает файловый дескриптор 3, поскольку он больше не нужен!
После выполнения приведенного выше сценария вы можете ожидать следующих результатов:
Сделайте больше, объединив exec с командой find
Знаете ли вы, что вы можете использовать команду find с исполнителем и, поверьте мне, это убийственная комбинация?
А если вы хотите научиться, вот подробное руководство:
Я надеюсь, что это руководство окажется для вас полезным. А если у вас есть сомнения, оставьте комментарий.