- •II. First steps on the command line
- •5. Man pages
- •6. Working with directories (работа с папками)
- •7.Working with files
- •8. Working with file contents
- •9. The Linux file tree
- •III. Shell expansion
- •10. Commands and arguments
- •11. Control operators
- •12. Variables
- •13. Shell history
- •14. File globbing
- •IV. Pipes and commands
- •Глава 16. Фильтры.
- •16.3 Grep
- •16.7. Sort
- •16.8. Uniq
- •16.9. Comm
- •16.12. Примеры пайпов
- •Глава 17. Основные инструменты Unix
- •17.1. Find
- •17.2. Размещение
- •17.3. Date
- •17.5. Sleep
- •17.6. Time
- •17.7. Gzip - gunzip
- •17.8. Zcat - zmore
- •18.3. Замена и удаление символов (r X X)
- •18.4. Отменить и повторить (u .)
- •18.5. Вырезать, копировать и вставить строчки (dd yy p p)
- •18.6. Вырезать, копировать и вставить строчки (3dd 2yy)
- •18.8. Объединения двух и более линий (j)
- •18.9. Слова (w b)
- •18.10. Сохранить (или нет) и выход (:w :q :q! )
- •18.11. Поиск (/ ?)
- •18.13. Чтение файлов (:r :r !cmd)
- •19.1. Предпосылки
- •19.2. Hello World
- •19.4. Комментарии
- •20.2. Если, затем, иначе (if then else)
- •20.3. If then elif
- •20.4. For loop
- •20.5. While loop
- •21.2. Shift through parameters.
- •21.3. Runtime input.
- •21.3. Sourcing a config file.
- •21.5. Get script options with getopts.
- •21.6. Get shell options with shopt.
- •Глава 22 More scripting.
- •22.1. Eval.
- •22.4. Case.
- •22.5. Shell functions.
- •Раздел VII. Local user management. Глава 23. Users.
- •23.1. Identify yourself.
- •23.2. Users.
- •23.3. Passwords.
- •23.4 Home directories
- •23.5 User shell
- •23.6. Switcj users with su
- •23.7 Run a program as another user
- •23.10 Shell environment
- •Глава 24. Groups
- •24.1 About groups
- •24.2 Groupadd
- •24.3 /Etc/group
- •24.4 Usermod
- •24.5 Groupmod
- •24.6 Groupdel
- •24.7 Groups
- •24.8 Gpasswd
- •24.9 Vigr
12. Variables
Тут будем рассматривать переменные.
$ - знак доллара
Еще один важный символ, интерпретируемый с помощью shell – знак $. Shell будет смотреть на переменную среды (environment variable) названную как строка, которая начинается знаком $ и заменяет её значением переменной (или ничем, если переменная не существует). Вот пример использования $HOSTNAME, $USER, $UID, $SHELL и $HOME:
[paul@RHELv4u3 ~]$ echo This is the $SHELL shell
This is the /bin/bash shell
[paul@RHELv4u3 ~]$ echo This is $SHELL on computer $HOSTNAME
This is /bin/bash on computer RHELv4u3.localdomain
[paul@RHELv4u3 ~]$ echo The userid of $USER is $UID
The userid of paul is 500
[paul@RHELv4u3 ~]$ echo My homedir is $HOME
My homedir is /home/paul
Имена переменных чувствительны к регистру:
[paul@RHELv4u3 ~]$ echo Hello $USER
Hello paul
[paul@RHELv4u3 ~]$ echo Hello $user
Hello
Переменная $SP1 отвечает за текст, который вы видите в начале командной строки (на примере будет ясно). Вы можете использовать обратный слеш, чтобы избежать спец символов, таких как \u для имени пользователя или \w для активной директории. Мануал bash содержит полную информацию.
В этом примере мы меняем переменную $PS1 несколько раз:
paul@deb503:~$ PS1=prompt
prompt #ввод текста сразу за словом prompt без пробела
promptPS1='prompt '
prompt #ввод текста после слова prompt через пробел
prompt PS1='> '
>
> PS1='\u@\h$ '
paul@deb503$
paul@deb503$ PS1='\u@\h:\W$'
paul@deb503:~$
Чтобы избежать неисправимых ошибок, вы можете изменить цвет текста для обычного пользователя на зеленый, а root пользователя на красный. Добавьте этот текст в ваш файл .bashrc для зеленого цвета строки у пользователя:
# color prompt by paul
RED='\[\033[01;31m\]'
WHITE='\[\033[01;00m\]'
GREEN='\[\033[01;32m\]'
BLUE='\[\033[01;34m\]'
export PS1="${debian_chroot:+($debian_chroot)}$GREEN\u$WHITE@$BLUE\h$WHITE\w\$ "
$PATH – переменная, которая определяет, где shell смотрит, какие команды исполнять (в случае, если команда не встроенная или замещенная псевдонимом). Эта переменная содержит список директорий, разделенных двоеточием:
[[paul@RHEL4b ~]$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:
Shell не будет искать в текущей директории исполняемые команды! (Эта уязвимость позволяла легко взламывать PC-DOS компьютеры). Если вы хотите, чтобы shell искал в текущей директории, то добавьте точку . в конец вашей переменной $PATH.
[paul@RHEL4b ~]$ PATH=$PATH:.
[paul@RHEL4b ~]$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:.
[paul@RHEL4b ~]$
Ваш путь может отличаться, если использовать “su” вместо “su -” потому что последний будет рассматривать как среду конечного пользователя. Обычно root пользователь имеет директорию /sbin добавленную к переменной $PATH:
[paul@RHEL3 ~]$ su
Password:
[root@RHEL3 paul]# echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
[root@RHEL3 paul]# exit
[paul@RHEL3 ~]$ su -
Password:
[root@RHEL3 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:
[root@RHEL3 ~]#
Создание переменных. Этот пример покажет создание переменной $MyVar и установит её значение. Затем используем команду echo чтобы проверить значение:
[paul@RHELv4u3 gen]$ MyVar=555
[paul@RHELv4u3 gen]$ echo $MyVar
555
[paul@RHELv4u3 gen]$
Обратите внимание, что двойные кавычки позволяют командам использовать переменные, в то время как одинарные не допускают этого:
[paul@RHELv4u3 ~]$ MyVar=555
[paul@RHELv4u3 ~]$ echo $MyVar
555
[paul@RHELv4u3 ~]$ echo "$MyVar"
555
[paul@RHELv4u3 ~]$ echo '$MyVar'
$MyVar
Bash shell будет заменять переменные на их значение в двойных кавычках, но не в одинарных:
paul@laika:~$ city=Burtonville
paul@laika:~$ echo "We are in $city today."
We are in Burtonville today.
paul@laika:~$ echo 'We are in $city today.'
We are in $city today.
Используйте команду set для того чтобы вывести список переменных в среде. В Ubuntu и Debian команда set также выведет список функций после переменных. Используйте set | more чтобы увидеть переменные.
Используйте команду unset, чтобы удалить переменную из своей shell среды:
[paul@RHEL4b ~]$ MyVar=8472
[paul@RHEL4b ~]$ echo $MyVar
8472
[paul@RHEL4b ~]$ unset MyVar
[paul@RHEL4b ~]$ echo $MyVar
[paul@RHEL4b ~]$
Команда env без опций покажет список экспортируемых переменных. Разница между set с опциями в том, что set показывает все переменные, включая те, которые не экспортируются в дочерние shell’ы.
Но env может также быть использована, чтобы создать новую, чистую оболочку (shell без какой-либо унаследованной среды). Команда env –i очищает среду для внутренней оболочки. Обратите внимание, что в примере bash сначала устанавливает переменную $SHELL при запуске.
[paul@RHEL4b ~]$ bash -c 'echo $SHELL $HOME $USER'
/bin/bash /home/paul paul
[paul@RHEL4b ~]$ env -i bash -c 'echo $SHELL $HOME $USER'
/bin/bash
[paul@RHEL4b ~]$
Вы можете использовать команду env для того, чтобы установить переменную $LANG, или любую другую, всего за одну команду bash. Пример ниже использует это, чтобы показать влияние переменной $LANG на файл подстановки.
[paul@RHEL4b test]$ env LANG=C bash -c 'ls File[a-z]'
Filea Fileb
[paul@RHEL4b test]$ env LANG=en_US.UTF-8 bash -c 'ls File[a-z]'
Filea FileA Fileb FileB
[paul@RHEL4b test]$
Вы можете экспортировать переменные среды с помощью команды export. Она позволит экспортировать переменные в дочерние оболочки.
[paul@RHEL4b ~]$ var3=three
[paul@RHEL4b ~]$ var4=four
[paul@RHEL4b ~]$ export var4
[paul@RHEL4b ~]$ echo $var3 $var4
three four
[paul@RHEL4b ~]$ bash
[paul@RHEL4b ~]$ echo $var3 $var4
four
Но не сможет экспортировать в родительскую оболочку (пример продолжается).
[paul@RHEL4b ~]$ export var5=five
[paul@RHEL4b ~]$ echo $var3 $var4 $var5
four five
[paul@RHEL4b ~]$ exit
exit
[paul@RHEL4b ~]$ echo $var3 $var4 $var5
three four
[paul@RHEL4b ~]$
Разграничение переменных. До сих пор мы видели, что bash интерпретирует переменные, начинающиеся со знака $ и продолжающихся до первого не алфавитно-цифрового символа, который не является нижним подчеркиванием. В некоторых ситуациях это может быть проблемой. Этот вопрос может быть решен с помощью фигурных скобок, как в примере:
[paul@RHEL4b ~]$ prefix=Super
[paul@RHEL4b ~]$ echo Hello $prefixman and $prefixgirl
Hello and
[paul@RHEL4b ~]$ echo Hello ${prefix}man and ${prefix}girl
Hello Superman and Supergirl
[paul@RHEL4b ~]$
Несвязанные переменные. В примере ниже пытаемся показать значение переменной $MyVar, но у нас не получается, поскольку переменная не существует. По умолчанию shell выведет пустоту, когда переменная не связана (не существует).
[paul@RHELv4u3 gen]$ echo $MyVar
[paul@RHELv4u3 gen]$
Однако существует опция nounset, которую можно использовать для создания текста ошибки, когда переменная не существует.
paul@laika:~$ set -u
paul@laika:~$ echo $Myvar
bash: Myvar: unbound variable
paul@laika:~$ set +u
paul@laika:~$ echo $Myvar
paul@laika:~$
В bash shell запись set –u идентична для set –o nounset и также set +u идентична для set +o nounset.
Опции оболочки. Обе команды set и unset являются встроенными командами shell. Они могут быть использованы для установки опций самой оболочки bash. Следующий пример пояснит это. По умолчанию, shell будет рассматривать неустановленные переменные, как переменные, у которых нет значения. Установив функцию –u, оболочка будет рассматривать любые ссылки на неустановленные переменные как ошибку. Загляните в мануал bash’а для большей информации.
[paul@RHEL4b ~]$ echo $var123
[paul@RHEL4b ~]$ set -u
[paul@RHEL4b ~]$ echo $var123
-bash: var123: unbound variable
[paul@RHEL4b ~]$ set +u
[paul@RHEL4b ~]$ echo $var123
[paul@RHEL4b ~]$
Чтобы вывести список всех опций вашей оболочки, используйте echo $-. Функция noclobber (или –C) будет объяснена позже в этой книге.
[paul@RHEL4b ~]$ echo $-
himBH
[paul@RHEL4b ~]$ set -C ; set -u
[paul@RHEL4b ~]$ echo $-
himuBCH
[paul@RHEL4b ~]$ set +C ; set +u
[paul@RHEL4b ~]$ echo $-
himBH
[paul@RHEL4b ~]$
Когда вводишь set без каких-либо опций, то получаешь список всех переменных без функций, когда оболочка находится в состоянии posix. Вы можете перевести bash в это состояние, напечатав set –o posix.
Вложенные оболочки. Оболочки могут быть встроены с помощью командной строки, или, другими словами, сканирование командной строки может породить новые процессы, содержащие ветвление текущей оболочки. Вы можете использовать переменные, чтобы доказать, что новые оболочки были созданы. В примере внизу переменная $var1 существует только во временной вложенной оболочке.
[paul@RHELv4u3 gen]$ echo $var1
[paul@RHELv4u3 gen]$ echo $(var1=5;echo $var1)
5
[paul@RHELv4u3 gen]$ echo $var1
[paul@RHELv4u3 gen]$
Вы можете вложить оболочку во вложенную оболочку, это называется сложным вложением оболочек (nested embedding of shells). Этот пример показывает вложенную оболочку внутри вложенной оболочки.
paul@deb503:~$ A=shell
paul@deb503:~$ echo $C$B$A $(B=sub;echo $C$B$A; echo $(C=sub;echo $C$B$A))
shell subshell subsubshell
Обратные кавычки. Единичное вложение может быть полезно, чтобы избежать изменения текущей директории. Пример показывает использование обратных кавычек вместо доллара и скобок для вложений:
[paul@RHELv4u3 ~]$ echo `cd /etc; ls -d * | grep pass`
passwd passwd- passwd.OLD
[paul@RHELv4u3 ~]$
Вы можете использовать только конструкцию $() для сложных вложений, обратные кавычки этого не могут.
Размещение вложения между обратными кавычками использует на 1 символ меньше, чем сочетание доллара и скобок. Однако будьте осторожны, очень легко перепутать одинарные и обратные кавычки. Техническое различие между ‘ и ` очень значительно!
[paul@RHELv4u3 gen]$ echo `var1=5;echo $var1`
5
[paul@RHELv4u3 gen]$ echo 'var1=5;echo $var1'
var1=5;echo $var1
[paul@RHELv4u3 gen]$