Shell

Материал из Etersoft wiki
Перейти к: навигация, поиск

Описание

Shell — это командный интерпретатор, с его помощью можно создавать скрипты, объединяя различные команды.

Подробное описание CodingStyle/Shell/TypicalCode


Каждый файл, призванный стать скриптом, должен начинаться с

#!/bin/sh

Следует иметь в виду, что реализаций /bin/sh несколько, и если вы пишете, используя конструкции, допустимые только в bash, следует писать

#!/bin/bash

Базовые конструкции

В написании скрипта можно использовать следующие конструкции: if while for .

If Базовый синтаксис: While For Case
if [ условие ] ; then
    echo "Hello"
fi
while [ условие ]
do
    echo "Hello"
done
for var in value1 value2 ...
do
    echo $var
done
case "$var" in
abc)  echo "$var = abc" ;;
xyz)  echo "$var = xyz" ;;
esac
If Объединение условий: While For пример Case
if [ -z "$MYZERO" ] && \
   [ "$2" != "$MYVAR" ] ; then
    echo "1"
elif [ "$MYZERO" = "$MYVAR" ] ; then
    echo "2"
else
    echo "default"
fi
 while read var1 var2 ; do
   echo $var1 $var2
 done < "$SERVFILE"
for i in {1..5}
do
   j=$((i+1))
   echo "Welcome $i times"
done
case "$var" in
exact)  echo "$var = exact" ;;
arg*)   echo "$var = arg...*";;
*)      echo "Default way";;
esac
Булевы операции: и &&, или ||, отрицание !
Напечатает Hello, если первое TRUE, а второе FALSE Найдет существующие файлы к которым нет доступа
if [ булево_выражение_1 ] && [ ! булево_выражение_2 ]; then
echo "Hello"
fi
if [ -e file ] || [ ! -r file ]; then
echo "File exist, but not readable"
fi
Функции
Объявление функции Вызов Вывод
equals(){
if [ "$1" == "$2" ]; then
    echo $1
else
    echo "Not equivalent"
fi
}
equals 3 4
Not equivalent
Импорт файла
#!/bin/sh
. /home/danil/Projects/autotest/my_script/function.sh

Теперь в новом файле можно использовать все функции из файла function.sh. Суть самой операции "." заключается во вставке текста импортируемого файла на место точки, как будто он там и набран.

Работа со строками:

сравнение строк

=
 
if [ "$a" = "$b" ]
 
==
 
if [ "$a" == "$b" ]
 
Синоним оператора =.
 
[[ $a == z* ]]    # истина, если $a начинается с символа "z" (сравнение по шаблону)
[[ $a == "z*" ]]  # истина, если $a равна z*
 
[ $a == z* ]      # имеют место подстановка имен файлов и разбиение на слова
[ "$a" == "z*" ]  # истина, если $a равна z*
 
[ -z "$a" ]    # строка "пустая", т.е. имеет нулевую длину
[ -n "$a" ]   # строка не "пустая".
Перенаправление вывода:

Направит stdout stderr (ошибки и вывод) в файл

cat /proc/cpuinf{\ ,o} &> $0.log # перезаписав его
cat /proc/cpuinf{\ ,o} >> $0.log 2>&1 # дописав его, команда 2>&1 направляет stderr в stdout

Только вывод, stdout

cat /proc/cpuinf{\ ,o} > $0.log # перезаписав его
cat /proc/cpuinf{\ ,o} >> $0.log # дописав его
Подстановки в переменных:
KEY="${4:-$SSH_KEY}"
Работа с файлами:

Операции возвращают true, если выполняются false иначе

-d file  directory
-e file  file exists
-r file  readable file
-s file  non-zero sized file
-w file  writable file
-x file  executable file

Пример:

Скипта:
#!/bin/sh
if [ -e /etc/lilo.conf ] # проверяем существует ли файл
then 
echo "Вы используете загрузчик lilo" # если выполняется, выводим надпись
fi

файл isLilo.sh

Цикла в одну строчку:
a=/srv/danil/Projects/runa/svn/runawfe-code/RunaWFE-4.x/trunk/projects/wfe; \
for i in $a/wfe-*; do echo "#Directory: $i" && cd "$i" && mvn -U package ; done \
>> ~/log3.runa 2> ~/log3.runa

Обновление ключей:

$ while read var1 var2 var3 ; do ssh-copy-id -i .ssh/id_ed25519.pub "$var2";  done < <(cat ~/.ssh/config | grep -v \# | grep -i Hostname)

functions

  • Дата
$(date +%H:%M:%S-%d.%m.%y) #01:18:21-19.05.16 дата - удобно для создания каталогов и файлов
  • Классный разбор аргументов
"`sed 's/&/%26/g;s/ /%20/g' <<<$@`" # превращение строки в правильный адрес  
grep -Eo 'http://[^"]+\.mp3' # поиск адреса по маске

Тонкости синтаксиса

$1 $2 нный аргумент переданный в скрипт или функцию
$0 echo $0 выведет bash
$# количество аргументов
$@ все переданные аргументы
$? код возврата

Оборачивать переменные в кавычки чтобы пробел не разбил один аргумент на несколько

C1DIR="/var/ftp/pvt/Windows/1C/1Cv82/"$C1VER"/"

Запись в файл

cat <<EOF >./wrote
#!/bin/sh
echo "Wrote!"
EOF

Задачи

Какие проблемы могут быть в этом коде?

myTrue(){
e="e"
echo -n "$e" > "$1"
myE=`cat "$1"`
if [ e==$myE ] ; than
    echo "it is equal"
fi
}

myTrue /dev/null

Вопросы

  • ${PATH#*:}, $(( 2#101011 )) Что значит ${#*:}, $(( ))
  • Регулярные выражения в grep
  • Хороший пример, но сложноватый

#!/bin/bash
SWINE="eter-1.0.12 eter-2.0 eter-2.1 eterhack eterwine etercad winevanilla eterschool"

for p in $SWINE ; do

DIR=$(find wine/$p/bottles/ -maxdepth 4 -mindepth 1 -type d   -name ".wine-*")

for i in $DIR ; do
     du -s -m $i | \
        while read size name ; do
            printf "%s\t%s%s\n" $size $(pwd)/$name
        done
done | sort -n >$p.txt

done
  • Интересный case из jboss-as-cp

while getopts “hc:l:p:” OPTION
do
     case $OPTION in
         h)
             usage
             exit 1
             ;;
         c)
             STANDALONE_XML=$OPTARG
             ;;
         l)
             LOCATION=$OPTARG
             ;;
         p)
             PORT_OFFSET=$OPTARG
             ;;
         ?)
             usage
             exit
             ;;
     esac
done
  • Замена
cat vksearch.out | sed -ne 's,<count>\([^<]*\)</count>,\1,p'|sed 's/^[ \t]*//'

на

grep -Po '<count\>\K.*?(?=</count\>)' vksearch.out

Ссылки

Подробное описание CodingStyle/Shell/TypicalCode

ShellCheck Online

Отличный учебник bash в пдф

Частые ошибки в bash

Синтаксис и команды shell (англ)

Искусство программирования на Shell и Bash

Advanced Bash-Scripting Guide

Сравнение shell и batch EOF

| Описание командного интерпретатора Bash

Полезные команды bash

Список сайтов о bash

[1]