[в закладки] bash для начинающих: 21 полезная команда

Синтаксис оператора if (краткое объяснение)

Основной синтаксис оператора if … then выглядит следующим образом:

if <condition>; then
<commands>
fi

Условие, в зависимости от его типа, окружено определенным
скобки, например. []. Вы можете прочитать о различных типах дальше
в учебнике. Вы можете добавить команды, которые будут выполняться, когда условие ложно, с помощью ключевого слова else и использовать ключевое слово elif (elseif) для выполнения команд с другим условием, если основное условие ложно. Ключевое слово else всегда стоит последним. Пример:

if ; then
        content=$(cat somefile)
elif ; then
        echo "The file 'somefile' exists but is not readable to the script."
else
        echo "The file 'somefile' does not exist."
fi

Краткое объяснение примера: сначала мы проверяем, является ли файл somefile читаемым («if »). Если так, мы читаем это в переменную. Если нет, мы проверяем, существует ли он на самом деле («elif »). Если это правда, мы сообщаем, что он существует, но не читается (если бы это было так, мы бы прочитали содержимое). Если файл не существует, мы также сообщаем об этом. Условие в elif выполняется только в том случае, если условие в if было ложным. Команды, принадлежащие else, выполняются, только если оба условия ложны.

Передача косвенной ссылки (Indirect References) в функцию

Самый интересный, функциональный и неуклюжий механизм :)
Это проще 1 раз увидеть, чем 100 раз услышать:

А теперь по-честному и по порядку

В отличии от некоторых других языков программирования, в
сценариях параметры в функцию обычно передаются по значению.
Если имена переменных (которые фактически являются указателями)
будут переданы в функцию в качестве параметров, то они будут обработаны,
как строковые литералы.Функции обрабатывают свои аргументы, как литералы.

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

Имя переменной — это «контейнер» для хранения значения данных.
Обращение к значению (получение значения) переменной называется подстановкой переменной.

Отмечу, что надо различать имя переменной и ее значение.
Если variable1 — имя переменной, то $variable1 — обращение к значению,
которое она содержит.

Имя переменной — в действительности, ссылка/указатель на область(ти) памяти,
где фактические данные связаны со значением, которое они хранят.

Как сказано выше, после подстановки переменной (referencing a variable, ),
мы получаем значение, на которую указывает переменная.
А как насчёт значения, на которое укзывает само значение? ?
Вы же помните, что с переменными мы работаем просто как с литералами? :)
Ну вот мы и пробуем получить значение, на которое указывает переменная,
имя которой тоже является значением другой переменной.
Немного запутанно, но, надеюсь, уловили.

Настоящая нотация выглядит как (или, c версии , как )
и обычно используется вместе с .
Данный механизм и называется косвенная ссылка (indirect reference).

Пример 2. Практичный

Так как имя переменной само хранится в переменной,
мы не можем установить его напрямую. Для этого используют .
Если в кратце, сообщает -интерпретатору, что необходимо
дважды проинтерпретировать строку. В первый раз он установит ,
а во второй — искомую переменную (которую передали как аргумент).

При сохранении имени переменной, которую передали как аргумент командной строки,
убедитесь, что сохраняете её локально и в переменную с отличным (по возможности)
именем, нежели использовалась в командной строке. Если этого не сделать,
и имя переменной, переданной как параметр командной строки, совпадёт с именем
локальной переменной, в которую Вы сохраняете значение, то ничего не будет работать :D

Пример 3. Не работающий!

Почему? Ну… в тот момент когда совершает вторую подстановку в
, — уже локальная переменная функции, поэтому
мы установим её ещё разок, а не искомую переменную.

Для большей гибкости, можно комбинировать разные подходы:

Где настраиваются редиректы

Настроить редирект можно несколькими способами.

Если ваш сайт работает на WordPress, проще всего использовать специальные плагины, например Redirection. Некоторые SEO-плагины в WordPress даже будут сами предлагать вам установить перенаправления, если вы удалите какую-либо страницу.

Настроить редирект можно также напрямую на сервере — так перенаправление будет происходить быстрее, чем в случае использования плагинов. Для этого нужно отредактировать файл .htaccess (если ваш сайт работает на веб-сервере Apache) или файлы конфигурации виртуальных доменов (если у вас сайт на сервере NGINX). 

Циклы перенаправлений

Циклы перенаправлений случаются когда за успешным перенаправлением следует другое, которое уже было выполнено. Другими словами, существует такой цикл, который никогда не закончится и в конечном счёте ни одна страница не будет найдена.

В большинстве случаев это проблема сервера, и если сервер не может обнаружить её, то отправит код статуса . Если вы встретите такую ошибку вскоре после редактирования настроек сервера, то это скорее всего цикл перенаправлений.

В случае, когда сервер не может обнаружить его: цикл перенаправлений может распространиться на несколько серверов, каждый из которых не имеет полной картины происходящего. В этом случае, браузеры покажут сообщение об ошибке. Firefox выведет:

тогда, как Chrome:

This Webpage has a redirect loop

В обоих случаях, пользователь не может ничего сделать (в отличие от ошибки на стороне клиента, например, несоответствие файлов куки или кеша).

Важно избегать циклов перенаправлений, так как они полностью нарушают работу пользователя

Точки зрения на редиректы

SEO — область знаний, которая полна мифов и гипотез. 

Ниже мы тезисно перечислим различные точки зрения о работе редиректов. Верить им или нет — оставляем на ваше усмотрение.

  1. 301 редирект не передает\передает санкции поисковых машин
  2. 302 редирект не передает\передает санкции поисковых машин 
  3. 302 редирект передает ссылочный вес в очень малом объеме

Куда вас отредиректили, или как не сломать все

Редиректы — это базовая механика, которую должен понимать каждый  SEO-специалист

Они имеют колоссальное влияние на оптимизацию сайта, поэтому очень важно использовать их правильно. Не злоупотребляйте HTML- и JS-перенаправлениями, используйте корректные коды ответа сервера и внимательно выбирайте страницу, на которую настраиваете редирект

Очень важно, чтобы ваши перенаправления не путали поисковых роботов и не вызывали недоумения у пользователей. 

Просмотры:
6 690

Александр Лушин

Александр Лушин — независимый SEO-эксперт. Занимается SEО и созданием сайтов с 2008 года. Специализируется на аудитах сайтов, поисковом продвижении и решениях под ключ. Руководит небольшой командой специалистов.

Примеры использования массивов Bash

Теперь рассмотрим примеры массивов bash. Сначала нам нужно создать массив, который мы будем использовать для примеров, на мой взгляд будет проще использовать синтаксис с круглыми скобками. Вообще, массивы используются в скриптах, но мы будем их применять прямо в оболочке Bash. Для начала так будет проще. Создаем массив:

Теперь попытаемся вывести один из элементов массива по его индексу:

Чаще всего используются массивы строк Bash, но иногда могут встречаться и цифры. Помните про нумерацию? Индексы элементов массива начинаются с нуля. Для вывода значения элемента по индексу можно использовать и немного другой синтаксис:

Вы можете вывести все элементы:

Все элементы, начиная с номера 1:

Вывести все элементы которые находятся в диапазоне от 1 до 4:

Чтобы узнать длину первого элемента выполните:

А посмотреть количество элементов массива Bash можно таким же синтаксисом:

Кроме всего прочего, вы можете заменить одни символы в определенном элементе массива или во всем массиве на другие. Для этого используйте:

В некоторых случаях, для перебора элементов массива очень удобно использовать циклы. На этот раз сделаем небольшой скрипт:

#!/bin/bash

array=(первый второй третий четвертый пятый)
for i in ${array}
do
echo $i
done

Внутри цикла вы можете делать со значением элемента все, что вам нужно. Как я уже писал выше, вы можете прочитать значения для массива с помощью функции read:

#!/bin/bash

echo «Введите элементы массива:»
read -a array
echo «Результат:»
for i in ${array}
do
echo $i
done

Как и в любом другом варианте, вам нужно, чтобы все элементы были разделены пробелом. Точно так же можно присвоить массиву результат выполнения команды. Например, сохраним список файлов, полученный от ls:

Усложним задачу и сделаем скрипт, который будет выводить все файлы из указанной директории, которые имеют права доступа 755:

#!/bin/bash

ERR=27
EXT=0

if ; then
echo «Используйте: $0 <путь>»
exit $ERR
fi

if ; then
echo «Каталог $1 не существует»
exit $ERR
fi

temp=( $(find $1 -maxdepth 1 -type f) )

for i in «${temp}»
do
perm=$(ls -l $i)
if ; then
echo ${i##*/}
fi
done

exit $EXT

Теперь проверим наш скрипт на папке /bin. Но перед этим нужно дать ему права на выполнение:

Как видите, все работает. Кроме номеров, в качестве индексов для массивов можно использовать строки. Такие массивы Bash называются ассоциативными и поддерживаются они начиная с четвертной версии Bash. Для создания ассоциативного массива используется declare с опцией -A:

Несмотря на то что Bash поддерживает только одномерные массивы, мы можем выполнять симуляцию работы с многомерными матрицами с помощью ассоциативных массивов:

Чтобы удалить массив, созданный с помощью declare используйте функцию unset:

Область действия переменных

Глобальные переменные — это переменные, к которым можно получить доступ из любого места в скрипте независимо от области видимости. В Bash все переменные по умолчанию определены как глобальные, даже если они объявлены внутри функции.

Локальные переменные могут быть объявлены в теле функции с ключевым словом и могут использоваться только внутри этой функции. Вы можете иметь локальные переменные с одинаковыми именами в разных функциях.

Чтобы лучше проиллюстрировать, как работает область видимости переменных в Bash, давайте рассмотрим этот пример:

~ / Variables_scope.sh

Сценарий начинается с определения двух глобальных переменных и . Затем есть функция, которая устанавливает локальную переменную и изменяет глобальную переменную .

Если вы запустите скрипт, вы должны увидеть следующий вывод:

Из приведенного выше вывода можно сделать вывод, что:

  • Когда локальная переменная устанавливается внутри тела функции с тем же именем, что и существующая глобальная переменная, она будет иметь приоритет над глобальной переменной.
  • Глобальные переменные могут быть изменены внутри функции.

Сопоставление функций с несколькими аргументами

Если аргументов несколько, компилятор по очереди применяет правила сопоставления к каждому аргументу. Выбирается так функция, для которой каждый аргумент соответствует по крайней мере так же хорошо, как и у всех других функций, причем по крайней мере один аргумент соответствует лучше, чем у всех других функций. Другими словами, выбранная функция должна обеспечивать лучшее соответствие, чем все другие функции-кандидаты, по крайней мере, по одному параметру и не хуже по всем остальным параметрам.

В случае, если такая функция будет найдена, это явный и однозначно лучший выбор. Если такая функция не найдена, вызов будет считаться неоднозначным (или без совпадений).

Например:

В приведенной выше программе все функции точно соответствуют по первому аргументу. Однако верхняя функция соответствует по второму параметру через числовое продвижение, тогда как другие функции требуют числового преобразования. Таким образом, однозначно является лучшим совпадением.

Определение функций Bash

Синтаксис объявления функции bash прост. Функции могут быть объявлены в двух разных форматах:

  1. Первый формат начинается с имени функции, за которым следуют скобки. Это предпочтительный и более используемый формат.

    Однострочная версия:

  2. Второй формат начинается с зарезервированного слова , за которым следует имя функции.

    Однострочная версия:

Несколько моментов, которые следует отметить:

  • Команды между фигурными скобками ( ) называются телом функции. Фигурные скобки должны быть отделены от тела пробелами или переводами строки.
  • Определение функции не выполняет ее. Чтобы вызвать функцию bash, просто используйте имя функции. Команды между фигурными скобками выполняются всякий раз, когда функция вызывается в сценарии оболочки.
  • Определение функции должно быть помещено перед любыми вызовами функции.
  • При использовании однострочных «уплотненных» функций точка с запятой должна следовать за последней командой в функции.
  • Всегда старайтесь, чтобы имена ваших функций были описательными.

Чтобы лучше это понять, взглянем на следующий пример:

~ / Hello_world.sh

Давайте проанализируем код построчно:

  • В строке 3 мы определяем функцию, присваивая ей имя. Фигурная скобка отмечает начало тела функции.
  • Линия — это тело функции. Тело функции может содержать несколько команд, операторов и объявлений переменных.
  • Линия , закрывающая фигурная скобка , определяет конец функции.
  • В строке мы выполняем функцию. Вы можете выполнять функцию столько раз, сколько вам нужно.

Если вы запустите скрипт, он напечатает .

Управляющая конструкция if-then-else

Для того, чтобы программа смогла сообщить и о результатах успешного поиска, и о неудаче, воспользуемся конструкцией . Вот как она устроена:

if команда
then
команды
else
команды
fi

Если первая команда возвратит ноль, что означает её успешное выполнение, условие окажется истинным и выполнение не пойдёт по ветке else. В противном случае, если будет возвращено что-то, отличающееся от нуля, что будет означать неудачу, или ложный результат, будут выполнены команды, расположенные после else.

#!/bin/bash

user=anotherUser
if grep $user /etc/passwd
then
echo "The user $user Exists"
else
echo "The user $user doesn’t exist"
fi

Проверки файлов

Kоманды позволяют проверять различные условия, касающиеся файлов

-d file         # Проверяет, существует ли файл, и является ли он директорией.
-e file         # Проверяет, существует ли файл.
-f file         # Проверяет, существует ли файл, и является ли он файлом.
-r file         # Проверяет, существует ли файл, и доступен ли он для чтения.
-s file         # Проверяет, существует ли файл, и не является ли он пустым.
-w file         # Проверяет, существует ли файл, и доступен ли он для записи.
-x file         # Проверяет, существует ли файл, и является ли он исполняемым.
file1 -nt file2 # Проверяет, новее ли file1, чем file2.
file1 -ot file2 # Проверяет, старше ли file1, чем file2.
-O file         # Проверяет, существует ли файл, и является ли его владельцем текущий пользователь.
-G file         # Проверяет, существует ли файл, и соответствует ли его идентификатор группы идентификатору группы текущего пользователя.

#!/bin/bash

mydir=/home/likegeeks

if                     # если файл сущетсвует и он является директорией
then
echo "The $mydir directory exists"  # выводим сообщение
cd $mydir                          # переходим в него 
ls                                  # отображаем содержимое
else                                # ИНАЧЕ
echo "The $mydir directory does not exist"
fi

Корректная процедура выполнения практического задания: перенаправление потоков ввода/вывода

1. Активируйте параметр командной оболочки .

set -o noclobber
set -C

2. Проверьте, активирован ли параметр , повторив вызов команды вывода содержимого директории для директории с перенаправлением данных из стандартного потока вывода в файл.

ls /etc > etc.txt 
ls /etc > etc.txt (команда не должна работать)

3. Какой из символов представляет параметр в списке всех параметров командной оболочки.

echo $- (параметр noclobber представлен символом C)

4. Деактивируйте параметр .

set +o noclobber

5. Убедитесь в том, что вы имеете доступ к двум командным оболочкам, открытым на одном компьютере. Создайте пустой файл . После этого выполните команду . Используйте вторую командную оболочку для строки текста в этот файл. Убедитесь в том, что эта строка была выведена в первой командной оболочке.

paul@deb503:~$ > tailing.txt
paul@deb503:~$ tail -f tailing.txt 
hello
world

в другой командной оболочке:
paul@deb503:~$ echo hello >> tailing.txt 
paul@deb503:~$ echo world >> tailing.txt

6. Создайте файл, содержащий имена пяти людей. Используйте команду и механизм перенаправления потоков ввода/вывода для создания файла, а также структуру для завершения ввода.

paul@deb503:~$ cat > tennis.txt < ace
> Justine Henin
> Venus Williams
> Serena Williams
> Martina Hingis
> Kim Clijsters
> ace
paul@deb503:~$ cat tennis.txt 
Justine Henin
Venus Williams
Serena Williams
Martina Hingis
Kim Clijsters
paul@deb503:~$
Предыдущий раздел: Оглавление Следующий раздел:
Глава 15. Формирование списков имен файлов на основе шаблонов   Глава 17. Фильтры

Перенаправление стандартного потока вывода

Операция перенаправления потока данных stdout (>)

Перенаправление стандартного потока вывода может быть осуществлено с помощью символа . В том случае, если при разборе строки команды командная оболочка обнаруживает символ знака >, она удаляет данные из файла и перенаправлет данные из стандартного потока вывода в него.

Нотация фактически является аббревиатурой для (в данном случае обозначается как поток номер ).

$ echo Сегодня холодно!
Сегодня холодно!
$ echo Сегодня холодно! > winter.txt
$ cat winter.txt 
Сегодня холодно!
$

Обратите внимание на то, что командная оболочка bash фактически описание операции перенаправления потока данных из строки команды перед исполнением этой команды, представленной аргументом 0. Это значит, что в случае исполнения данной команды:

echo привет > greetings.txt

командная оболочка будет рассматривать только два аргумента (echo = аргумент 0, привет = аргумент 1). Описание операции перенаправления потока данных удаляется перед началом подсчета количества аргументов.

Содержимое выходного файла удаляется

В том случае, если в процессе разбора строки команды командная оболочка обнаружит символ знака >, ! Ввиду того, что описанная процедура выполняется перед извлечением , содержимое файла будет удалено даже в случае неудачного исполнения команды!

$ cat winter.txt 
Сегодня холодно!
$ zcho Сегодня холодно! > winter.txt
-bash: zcho: команда не найдена..
$ cat winter.txt 
$

Параметр командной оболочки noclobber

Удаление содержимого файла при использовании оператора может быть предотвращено путем установки параметра командной оболочки .

$ cat winter.txt 
Сегодня холодно!
$ set -o noclobber
$ echo Сегодня холодно! > winter.txt
-bash: winter.txt: не могу переписать уже существующий файл
$ set +o noclobber
$

Нейтрализация влияния параметра командной оболочки noclobber

Влияние параметра командной оболочки может быть нейтрализовано с помощью оператора .

$ set -o noclobber
$ echo Сегодня холодно! > winter.txt
-bash: winter.txt: не могу переписать уже существующий файл
$ echo Сегодня очень холодно! >| winter.txt
$ cat winter.txt 
Сегодня очень холодно!
$

Оператор дополнения >>

Следует использовать оператор для записи данных из стандартного потока вывода в конец файла без предварительного удаления содержимого этого файла.

$ echo Сегодня холодно! > winter.txt
$ cat winter.txt 
Сегодня холодно!
$ echo Когда же наступит лето ? >> winter.txt
$ cat winter.txt 
Сегодня холодно!
Когда же наступит лето ?
$
Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: