{{tag>bash developing develop}}

====== Bash ======

===== Файлы конфигурации: .profile .bash_profile и .bashrc итд =====

==== В чем отличие .bash_profile и .bashrc? ====

.bash_profile загружается только при входе пользователя в систему (консольный вход, ssh), 
в то время как  .bashrc запускается для интерактивных сервисов выполняемых без
логина (запуск xterm).
===== Переменные и параметры =====


|$$	|pid текущего shell (самого процесса-сценария)|
|$!	|pid последнего процесса в фоновом режиме|
|$?	|код возврата последнего процесса (функции или скрипта)|
|$x	|где x — номер параметра, переданного скрипту ($1, $2 и т. д., $0 — последний запущенный скрипт)|
|$#	|количество аргументов командной строки|
|$*	|все аргументы в виде одной строки (слова)|
|$@	|то же самое, что и $*, но при этом каждый параметр представлен как отдельная строка (слово)|
|$-	|список флагов, переданных сценарию|
|$_	|содержит последний аргумент предыдущей команды|

===== Потоки вывода и файловые дескрипторы =====

  * du -h 1 > ./log 2>&1

|Наименование|Описание|
|1| Поток вывода|
|2| Поток ошибок|
|&1|обозначает файловый дескриптор 1|


===== Конструкции =====

===== 0-9 =====
===== A =====

==== Массивы ====

<code bash>
array=( one two three )
files=( "/etc/passwd" "/etc/group" "/etc/hosts" )
limits=( 10, 20, 26, 39, 48)
</code>

==== ARGV ====

<code bash>
# ------------- SCRIPT ------------- #

#!/bin/bash

echo
echo "# arguments called with ---->  ${@}     "
echo "# \$1 ---------------------->  $1       "
echo "# \$2 ---------------------->  $2       "
echo "# path to me --------------->  ${0}     "
echo "# parent path -------------->  ${0%/*}  "
echo "# my name ------------------>  ${0##*/} "
echo
exit

# ------------- CALLED ------------- #

# Notice on the next line, the first argument is called within double, 
# and single quotes, since it contains two words

$  /misc/shell_scripts/check_root/show_parms.sh "'hello there'" "'william'"

# ------------- RESULTS ------------- #

# arguments called with --->  'hello there' 'william'
# $1 ---------------------->  'hello there'
# $2 ---------------------->  'william'
# path to me -------------->  /misc/shell_scripts/check_root/show_parms.sh
# parent path ------------->  /misc/shell_scripts/check_root
# my name ----------------->  show_parms.sh

# ------------- END ------------- #
</code>
===== B =====
===== C =====

==== case ====

<code>
case "$1" in
start)
esac
</code>

==== cut ====

микропрограмма для работы с текстом

Параметры:
  * -d
  * -f(число)

Переименовывает все файлы вида thread_1_seq_35970.1752.876204343 в файлы вида arch_1_0000035970_869578613.arc
<code bash>
#! /bin/bash
FOUND=0
for filename in *
do
  echo "$filename" | grep -q "thread_1_seq_"

  if [ $? -eq $FOUND ]; then
    part=`echo $filename | cut -d "_" -f4 | cut -d "." -f1`
    mv "$filename" "arch_1_00000${part}_869578613.arc"
  fi

done
</code>
===== D ===== 

==== debug ====

Необходимо добавить параметр -x
Пример:
<code># bash -x script.sh</code>

==== dialog ====

Представляет из себя интерфейс для библиотеки ncurses. И позволяет строить диалоги из скрипта. Альтернативой dialog может служить whiptail, который даже присутствует в некоторых системах по умолчанию.

[[system:dialog|]]

<code bash>
#!/usr/bin/bash

Choice=`$Dialog --stdout --clear --menu "Выберите файл" 20 71 14 $Spisok`
retval=$?

case $retval in
    0)
esac
</code>
===== E =====
===== F =====

==== function ====

<code bash>
function f1{

	# params $1
	echo $1

}

f1 A
</code>

==== foreach ====

<code bash>
for fn in `cat filenames.txt`; do
    echo "the next file is $fn"
    cat $fn
done
</code>

<code bash>
while read filename
do
    echo "Printing: $filename"
    cat "$filename"
done < filenames.txt
</code>

<code bash>
for fn in cat filenames.txt; do cat "$fn"; done
</code>

<code bash>
for i in "${arrayName[@]}"
do
   :
   # do whatever on $i
done
</code>
===== G =====
===== H =====

<code bash>

Choice="Y"

cat << EOF_CONFIG > $config
client
remote xxxxx
port 1194
proto udp
dev tun
ns-cert-type server
tls-client
reneg-sec 60
mtu-test
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
keysize 256
nobind
explicit-exit-notify 2
pkcs12 yyy/$Choice
EOF_CONFIG

echo $config
</code>
===== I =====

=== Индексы ===

  * [@] - Ссылка на копию массива в переменной $1
  * [*] - Строка 
  * [n]

  * var=(1 2 3 4)
  * echo ${var[@]}

=== if ===


<code bash>
if что-то
then
 # делать тот-то
else
 # делать тот-то
fi
</code>

<code bash>
if что-то; then
 # делать тот-то
else
 # делать тот-то
fi
</code>

=== input ===

Запрос символа от пользователя

<code bash>
echo -n "Продолжить? (y/n) "

read item
case "$item" in
    y|Y) echo "Ввели «y», продолжаем..."
        ;;
    n|N) echo "Ввели «n», завершаем..."
        exit 0
        ;;
    *) echo "Ничего не ввели. Выполняем действие по умолчанию..."
        ;;
esac
</code>

===== J =====
===== K =====
===== L =====
===== M =====
===== N =====
===== O =====

==== echo ====

Вывод прогресс бара
<code bash>
$ echo -ne '#####                     (33%)\r'
</code>

===== P =====
===== Q =====
===== R =====

<code bash>
$ IFS=' ' read -r -a DATABASES_SELECTED <<< "$DATABASES_SELECTED"
$ read str <<< "  x  "; echo "-$str-"
-x-
$ IFS="" read str <<< "  x  "; echo "-$str-"
-  x  -
$ IFS= read str <<< "  x  "; echo "-$str-"
-  x  -
$ _
</code>

  * IFS=";" выставляем делимитер разбивки (в нашем случае ";")
  * set -- $line - разбиваем строку, после чего каждая ее часть будет доступна как $1, $2, ...
===== S =====


==== select ====

<code bash>
select action in "Опция 1" "Опция 2" "Выход" 
do 
echo $action 
test $action = "Выход" && break 
done 
</code>
===== T =====

====== test ======

  * Параметры:
      * ''-b file'' — истина, если file существует и является специальным блочным устройством.
      * ''-c file'' — истина, если file существует и символьное устройство.
      * ''-d file'' — истина, если file существует и является каталогом.
      * ''-e file'' — истина, если file существует.
      * ''-f file'' — истина, если file существует и является обычным файлом.
      * ''-g file'' — истина, если file существует и имеет установленным групповой идентификатор (set-group-id).
      * ''-k file'' — истина, если file имеет установленным «sticky» бит.
      * ''-L file'' — истина, если file существует и является символьной ссылкой.
      * ''-p file'' — истина, если file существует и является именованным каналом (pipe).
      * ''-r file'' — истина, если file существует и читаем.
      * ''-s file'' — истина, если file существует и имеет размер больше, чем ноль.
      * ''-S file'' — истина, если file существует и является сокетом.
      * ''-t [fd]'' — истина, если fd открыт на терминале. Если fd пропущен, по умолчанию 1 (стандартное устройство вывода).
      * ''-u file'' — истина, если file существует и имеет установленным бит пользователя (set-user-id).
      * ''-w file'' — истина, если file существует и записываем.
      * ''-x file'' — истина, если file существует и исполняем.
      * ''-O file'' — истина, если file существует и его владелец имеет эффективный идентификатор пользователя.
      * ''-G file'' — истина, если file существует и его владелец имеет эффективный идентификатор группы.
      * ''file1 -nt file2'' — истина, если file1 новее (дата модификации), чем file2.
      * ''file1 -ot file2'' — истина, если file1 старее, чем file2.
      * ''file1 -ef file2'' — истина, если file1 и file2 имеют то же устройство и номер inode.
      * ''-z string'' — истина, если длина string равна нулю.
      * ''-n string'' — истина, если длина string не ноль.
      * ''string1 = string2'' — истина, если строки равны.
      * ''string1 != string2'' — истина, если строки не равны.
      * ''! expr'' — истина, если выражение expr ложь.
      * ''expr1 -a expr2'' — истина, если оба выражения expr1 и expr2 истина.
      * ''expr1 -o expr2'' — истина, если хотя бы одно из выражений expr1 или expr2 истина.
      * ''arg1 %оператор% arg2 -eq, -ne, -lt, -le, -gt, или -ge'' — эти арифметические бинарные операции возвращают истину, если arg1 равно (-eq), не равно (-ne), меньше чем (-lt), меньше чем или равно (-le), больше чем (-gt), или больше или равно (-ge), чем arg2, соответственно. arg1 и arg2 могут быть положительными целыми, отрицательными целыми, или специальными выражениями -l string, которые вычисляют длину string.
  * Сокращенный вариант **[ ]**


===== Применение в коде =====

<code bash>
if [ $daynow != 1 ]; then
# ....
fi

if [ $daynow -ge 1 ] && [ $daynow -le 7 ]; then
# ....
fi
</code>

Сравнение **-eq** с **==**

<code bash>
$ [ a == a ]; echo $?
0

$ [ a -eq a ]; echo $?
-bash: [: a: integer expression expected
2
</code>

=== status ===

Проверка статуса выполнения программы

<code bash>
rm test_file

if [ $? -eq 0 ]; then
    echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]"
    echo
else
    echo -n "$(tput hpa $(tput cols))$(tput cub 6)[fail]"
    echo
fi
</code>

====== tput ======

Команда tput инициализирует и управляет вашими сеансами работы с терминалом, используя базу данных terminfo. С помощью tput вы можете управлять различными функциями терминала, такими как перемещение или изменение вида курсора, изменение свойств текста и очистка определенных областей экрана терминала.

  * tput hpa N — сдвиг курсора на N позиций
  * tput cols получает ширину окна терминала
  * tput cub 6 — сдвигает курсор на 6 позиций влево

Также можно выставить цвет

  * tput setaf 0..7 — цвет текста
  * tput setab 0..7 — цвет фона
  * tput sgr0 — сброс на дефолтный

Подробнее: http://www.ibm.com/developerworks/ru/library/au-learningtput/
===== U =====
===== V =====
===== W =====
===== X =====
===== Y =====


