Введение
В этой лабораторной работе вы познакомитесь со специальными переменными в программировании на Shell. Эти переменные предоставляют важную информацию о среде выполнения скрипта, такую как аргументы командной строки, имя самого скрипта и идентификатор процесса. Понимание этих переменных поможет вам писать более гибкие и функциональные сценарии.
Создание первого скрипта
Начнем с создания простого shell-скрипта для демонстрации использования специальных переменных.
Откройте терминал в WebIDE. Вы увидите приглашение командной строки, ожидающее ввода.
Перейдите в каталог проекта:
cd ~/project
Эта команда меняет текущий каталог на ~/project, который является рабочим каталогом по умолчанию для этой лабораторной работы.
- Создайте новый файл с именем
special_vars.shс помощью следующей команды:
touch special_vars.sh
Команда touch создает пустой файл, если он не существует, или обновляет время его изменения, если он уже есть.
Откройте файл в редакторе WebIDE. Для этого щелкните по имени файла в проводнике слева.
Добавьте в файл следующее содержимое:
#!/bin/bash
echo "Script Name: $0"
echo "First Argument: $1"
echo "Second Argument: $2"
echo "All Arguments: $@"
echo "Number of Arguments: $#"
echo "Process ID: $$"
Разберем, что делает каждая строка:
#!/bin/bash: Это шебанг (shebang). Он указывает системе использовать bash для интерпретации этого скрипта.$0: Эта специальная переменная хранит имя скрипта.$1и$2: Они представляют собой первый и второй аргументы командной строки соответственно.$@: Представляет все аргументы командной строки, переданные скрипту.$#: Возвращает количество переданных аргументов.$$: Предоставляет идентификатор процесса (PID) текущей оболочки.
Сохраните файл после добавления содержимого.
Сделайте скрипт исполняемым, выполнив следующую команду в терминале:
chmod +x special_vars.sh
Команда chmod изменяет права доступа к файлу. Опция +x добавляет право на выполнение, что позволяет вам запускать скрипт.
Запуск скрипта с аргументами
Теперь, когда скрипт создан, давайте запустим его с различными аргументами, чтобы увидеть, как ведут себя специальные переменные.
- Запустите скрипт без аргументов:
./special_vars.sh
Символы ./ перед именем файла указывают оболочке искать скрипт в текущем каталоге.
Вы должны увидеть вывод, похожий на этот:
Script Name: ./special_vars.sh
First Argument:
Second Argument:
All Arguments:
Number of Arguments: 0
Process ID: 1234
Обратите внимание, что первый и второй аргументы пусты, а количество аргументов равно 0, так как мы ничего не передали.
- Теперь запустите скрипт с несколькими аргументами:
./special_vars.sh hello world
Вывод должен выглядеть так:
Script Name: ./special_vars.sh
First Argument: hello
Second Argument: world
All Arguments: hello world
Number of Arguments: 2
Process ID: 1235
Что изменилось:
$1теперь содержит "hello"$2теперь содержит "world"$@показывает все аргументы: "hello world"$#показывает 2, так как мы передали два аргумента
Идентификатор процесса ($$) может меняться при каждом запуске, так как он назначается операционной системой динамически.
Понимание $? и $!
Еще две важные специальные переменные — это $? и $!. Создадим новый скрипт для демонстрации их работы.
- Создайте новый файл с именем
exit_status.sh:
touch ~/project/exit_status.sh
- Откройте файл в редакторе WebIDE и добавьте следующее содержимое:
#!/bin/bash
echo "Running a successful command:"
ls /home
echo "Exit status: $?"
echo "Running a command that will fail:"
ls /nonexistent_directory
echo "Exit status: $?"
echo "Running a background process:"
sleep 2 &
echo "Process ID of last background command: $!"
Разберем этот скрипт:
$?возвращает код завершения последней выполненной команды. 0 обычно означает успех, а любое другое значение указывает на ошибку.$!возвращает идентификатор процесса (PID) последней команды, запущенной в фоновом режиме.- Символ
&в конце команды запускает её в фоновом режиме.
- Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/exit_status.sh
- Запустите скрипт:
./exit_status.sh
Вы увидите примерно такой вывод:
Running a successful command:
labex
Exit status: 0
Running a command that will fail:
ls: cannot access '/nonexistent_directory': No such file or directory
Exit status: 2
Running a background process:
Process ID of last background command: 1236
Обратите внимание:
- Первая команда
lsвыполнена успешно, поэтому$?равен 0. - Вторая команда
lsзавершилась с ошибкой (так как каталог не существует), поэтому$?равен 2 (ненулевое значение, указывающее на ошибку). - Команда
sleepработает в фоне, и$!показывает её PID.
Использование специальных переменных в функциях
Специальные переменные также можно использовать внутри функций. Создадим скрипт для проверки этого поведения.
- Создайте новый файл с именем
function_vars.sh:
touch ~/project/function_vars.sh
- Откройте файл в редакторе WebIDE и добавьте следующее содержимое:
#!/bin/bash
function print_args {
echo "Function Name: $0"
echo "First Argument: $1"
echo "Second Argument: $2"
echo "All Arguments: $@"
echo "Number of Arguments: $#"
}
echo "Calling function with two arguments:"
print_args hello world
echo "Calling function with four arguments:"
print_args one two three four
Этот скрипт определяет функцию print_args, использующую специальные переменные, и вызывает её дважды с разным количеством аргументов.
- Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/function_vars.sh
- Запустите скрипт:
./function_vars.sh
Вывод будет примерно таким:
Calling function with two arguments:
Function Name: ./function_vars.sh
First Argument: hello
Second Argument: world
All Arguments: hello world
Number of Arguments: 2
Calling function with four arguments:
Function Name: ./function_vars.sh
First Argument: one
Second Argument: two
All Arguments: one two three four
Number of Arguments: 4
Заметьте, что:
$0по-прежнему ссылается на имя скрипта, а не на имя функции.$1,$2,$@и$#работают для аргументов функции точно так же, как и для аргументов скрипта.- Значения этих переменных меняются при каждом вызове функции в зависимости от переданных ей данных.
Разница между $@ и $*
Специальные переменные $@ и $* используются для представления всех аргументов командной строки, но они ведут себя по-разному, если заключены в двойные кавычки. Создадим скрипт, чтобы увидеть разницу.
- Создайте новый файл с именем
at_vs_star.sh:
touch ~/project/at_vs_star.sh
- Откройте файл в редакторе WebIDE и добавьте следующее содержимое:
#!/bin/bash
echo "Using \$@:"
for arg in "$@"; do
echo "Argument: $arg"
done
echo "Using \$*:"
for arg in "$*"; do
echo "Argument: $arg"
done
Этот скрипт демонстрирует различие между $@ и $* при использовании в цикле.
- Сохраните файл и сделайте его исполняемым:
chmod +x ~/project/at_vs_star.sh
- Запустите скрипт с несколькими аргументами, включая аргументы с пробелами:
./at_vs_star.sh "arg with spaces" another_arg "third arg"
Вывод будет выглядеть так:
Using $@:
Argument: arg with spaces
Argument: another_arg
Argument: third arg
Using $*:
Argument: arg with spaces another_arg third arg
Вот что происходит:
- При использовании
"$@"каждый аргумент обрабатывается как отдельный объект. Аргументы с пробелами сохраняются как единые элементы. - При использовании
"$*"все аргументы объединяются в одну строку, разделенную первым символом переменной IFS (обычно это пробел).
Эта разница критически важна, когда вам нужно обрабатывать аргументы, которые могут содержать пробелы или другие специальные символы.
Резюме
В этой лабораторной работе вы изучили специальные переменные в Shell и научились эффективно их использовать. Вы создали скрипты, демонстрирующие работу таких переменных, как $0, $1, $@, $#, $$, $? и $!. Вы также узнали, как эти переменные ведут себя в различных контекстах, включая функции и обработку аргументов командной строки.
Основные выводы:
$0,$1,$2и т.д. представляют имя скрипта и его аргументы.$@и$#позволяют работать со всеми аргументами сразу и узнавать их количество.$$возвращает PID текущего процесса, что полезно для создания уникальных временных файлов.$?помогает проверить, успешно ли завершилась предыдущая команда.$!возвращает PID последнего фонового процесса, что удобно для управления задачами."$@"и"$*"ведут себя по-разному при использовании кавычек, что важно для корректной обработки аргументов с пробелами.
Понимание этих специальных переменных необходимо для написания продвинутых и гибких скриптов. Они позволяют создавать сценарии, адаптирующиеся к входным данным и предоставляющие важную информацию о среде выполнения.
Продолжая практиковаться, вы найдете еще много способов применения этих переменных в своей работе. Для получения более подробной информации всегда можно обратиться к руководству bash (man bash).



