Домашняя » как » Руководство для начинающих по сценариям оболочки 2 для циклов

    Руководство для начинающих по сценариям оболочки 2 для циклов

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

    Пересмотренный скрипт datecp

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

    Сэмюэль Дионн-Риель отметил в комментариях, что есть намного лучший способ справиться с нашими переменными ссылками.

    Аргументы разделены пробелом в оболочке bash, он будет разбит на токены, если в полученной расширенной команде есть пробел. В вашем скрипте, cp $ 1 $ 2. $ date_formatted будет работать так, как задумано, если в расширенных переменных нет пробелов. Если вы называете свой сценарий так: datecp "мое старое имя" "мое новое имя" расширение приведет к этой команде: cp мое новое имя мое старое имя.дата который на самом деле имеет 6 аргументов.

    Чтобы правильно решить эту проблему, последняя строка скрипта должна быть: cp "$ 1" "$ 2. $ date_formatted"

    Как видите, изменив строку нашего скрипта с:

    cp -iv $ 1 $ 2. $ date_formatted

    чтобы:

    cp -iv «$ 1» «$ 2». $ date_formatted

    позаботится об этой проблеме при использовании скрипта на файлах с пробелами в имени. Сэмюэл также подчеркивает, что при копировании и вставке кода с этого сайта (или Интернета в целом) обязательно замените правильные тире и кавычки на «типографски лучшие», которые часто заменяют их. Мы также сделаем больше, чтобы наш код был более дружественным к копированию / вставке. ;-)

    Другой комментатор, Майлз Брейтвейт, решил расширить наш сценарий, чтобы дата появлялась перед расширением файла. Так что вместо

    tastyfile.mp3.07_14_11-12.34.56

    мы бы получили это:

    tastyfile.07_14_11-12.34.56.mp3

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

    date_formatted = $ (дата +% Y-% m-% d_% H.% M% S)
    file_extension = $ (echo «$ 1" | awk -F. 'print $ NF')
    имя_файла = $ (базовое имя $ 1. $ file_extension)

    cp -iv $ 1 $ file_name- $ date_formatted. $ file_extension

    Я немного изменил форматирование, но вы можете видеть, что Майлз объявляет свою функцию даты в строке 1. Однако в строке 2 он использует команду «echo» с первым аргументом сценария для вывода имени файла. Он использует команду pipe, чтобы получить этот вывод и использовать его в качестве ввода для следующей части. После конвейера Myles вызывает команду «awk», которая является мощной программой сканирования паттернов. Используя флаг -F, он сообщает команде, что следующий символ (после пробела) - это то, что будет определять «разделитель полей». В данном случае это период.

    Теперь, awk видит файл с именем «tastyfile.mp3», состоящий из двух полей: «вкусный файл» и «mp3». Наконец, он использует

    'print $ NF'

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

    В строке 3 он создает новую переменную для имени файла и использует команду «basename» для ссылки на все в $ 1. Кроме расширение файла. Это делается путем использования базового имени и предоставления ему $ 1 в качестве аргумента, а затем добавления пробела и расширения файла. Расширение файла автоматически добавляется из-за переменной, которая ссылается на строку 2. Что бы это сделать, это взять

    tastyfile.mp3

    и превратить его в

    tastyfile

    Затем в последней строке Майлз собрал команду, которая выведет все по порядку. Обратите внимание, что нет ссылки на $ 2, второй аргумент для скрипта. Этот конкретный сценарий скопирует указанный файл в ваш текущий каталог. Отличная работа Сэмюэл и Майлз!

    Запуск скриптов и $ PATH

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

    ./ скрипт

    ~ / Бен / скрипт

    Но, поместив свои скрипты в ~ / bin /, вы можете просто ввести их имена из любого места, чтобы заставить их работать.

    Комментаторы провели некоторое время, обсуждая, насколько это правильно, поскольку ни один современный дистрибутив Linux не создает этот каталог по умолчанию. Более того, по умолчанию никто не добавляет его в переменную $ PATH, что необходимо для запуска сценариев подобно командам. Я был немного озадачен, потому что после проверки моей переменной $ PATH, комментаторы были правы, но вызов сценариев все еще работал для меня. Я выяснил почему: многие современные дистрибутивы Linux создают специальный файл в домашнем каталоге пользователя - .profile.

    Этот файл читается bash (если только .bash_profile присутствует в домашнем каталоге пользователя), а внизу есть раздел, в котором папка ~ / bin / добавляет переменную $ PATH, если она существует. Итак, эта тайна разгадана. В оставшейся части серии я продолжу помещать сценарии в каталог ~ / bin /, потому что они являются пользовательскими сценариями и должны запускаться пользователями. И, похоже, нам не нужно возиться с переменной $ PATH вручную, чтобы все заработало.

    Повторение команд с циклами

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

    Основная схема цикла for выглядит следующим образом:

    для переменной в списке; делать
    command1
    command2
    ...
    commandn
    сделанный

    VARIABLE может быть любой переменной, хотя чаще всего строчная буква «i» используется по соглашению. LIST - список товаров; Вы можете указать несколько элементов (разделяя их пробелом), указать внешний текстовый файл или использовать звездочку (*) для обозначения любого файла в текущем каталоге. Перечисленные команды имеют отступы по соглашению, так что проще видеть вложенность - помещая циклы в циклы (так что вы можете создавать циклы во время цикла).

    Поскольку в списках в качестве разделителей используются пробелы, то есть пробел означает переход к следующему элементу в списке, файлы с пробелами в имени не очень удобны. А сейчас давайте продолжим работу с файлами без пробелов. Начнем с простого скрипта для отображения имен файлов в текущем каталоге. Создайте новый скрипт в папке ~ / bin / под названием «loopscript». Если вы не помните, как это сделать (в том числе пометить его как исполняемый файл и добавить хак-хэш-взлом), обратитесь к нашей статье об основах сценариев bash..

    В нем введите следующий код:

    для меня в item1 item2 item3 item4 item5 item6; делать
    эхо «$ я»
    сделанный

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

    Довольно просто, правда? Посмотрим, что произойдет, если мы немного изменим ситуацию. Измените ваш сценарий так, чтобы он говорил так:

    ибо я в *; делать
    эхо «$ я»
    сделанный

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

    Теперь давайте изменим команду echo на что-то более полезное, скажем, команду zip. А именно, мы будем добавлять файлы в архив. И давайте получим некоторые аргументы в смеси!

    для меня в $ @; делать
    почтовый архив «$ i»
    сделанный

    Там что-то новое! «$ @» - это сокращение от «$ 1 $ 2 $ 3… $ n». Другими словами, это полный список всех аргументов, которые вы указали. Теперь посмотрите, что происходит, когда я запускаю скрипт с несколькими входными файлами.

    Вы можете увидеть, какие файлы находятся в моей папке. Я выполнил команду с шестью аргументами, и каждый файл был добавлен в архив с именем «archive.zip». Легко, верно?

    Ибо петли довольно замечательные. Теперь вы можете выполнять пакетные функции в списках файлов. Например, вы можете скопировать все аргументы вашего скрипта в заархивированный архив, переместить оригиналы в другую папку и автоматически защитить копию этого zip-файла на удаленном компьютере. Если вы настроили файлы ключей с помощью SSH, вам даже не нужно будет вводить пароль, и вы даже можете сказать скрипту удалить файл zip после загрузки его!


    Использование for-loop позволяет легко выполнять кучу действий для всех файлов в каталоге. Вы можете объединять самые разные команды и очень легко использовать аргументы для создания и быстрого создания списка, и это только вершина айсберга..

    Сценаристы Bash, у вас есть предложения? Вы сделали полезный скрипт, который использует циклы? Хотите поделиться своими мыслями о сериале? Оставьте некоторые комментарии и помогите другим новичкам сценариев!