Посібник для початківців для сценаріїв Shell 2 для циклів
Якщо ви хочете створити свій комп'ютерний комп'ютер, приєднайтеся до нас на другий внесок у нашій серії сценаріїв. У нас є кілька виправлень, кілька поліпшень сценарію минулого тижня, а також керівництво по циклу для непосвячених.
Переглянуто сценарій datecp
У першій частині нашого керівництва сценаріїв оболонки ми зробили скрипт, який скопіював файл у резервну копію після додавання дати до кінця імені файлу..
Самуїл Діоне-Ріель зазначив у коментарях, що є набагато кращий спосіб обробляти наші посилання на змінні.
Аргументи розділені пробілами в оболонці bash, вона буде маркірувати, коли в наведеної розгорнутої команди буде пробіл. У вашому сценарії,
cp $ 1 $ 2. $ date_formatted
буде працювати за призначенням до тих пір, поки розширені змінні не матимуть пробілів у них. Якщо ви називаєте свій сценарій таким чином:datecp "моя стара назва" "моя нова назва"
розширення призведе до цієї команди:cp нове ім'я мій старий name.the_date
що насправді має 6 аргументів.Щоб правильно вирішити цю проблему, останній рядок сценарію повинен бути:
cp "$ 1" "$ 2. $ date_formatted"
Як ви можете бачити, змінюючи рядок нашого сценарію з:
cp -iv $ 1 $ 2. $ date_formatted
до:
cp -iv “$ 1” “$ 2”. $ date_formatted
буде піклуватися про цю проблему при використанні сценарію на файлах, які мають пробіли в імені. Самуїл також вказує на те, що при копіюванні та вставці коду з цього сайту (або Інтернету взагалі) обов'язково замінюйте відповідні тире і котирування на «типографічно кращі», які часто замінюють їх. Ми також зробимо більше, щоб переконатися, що наш код є більш дружнім для копіювання / вставки. ;-)
Інший коментатор, Myles Braithwaite, вирішив розширити наш сценарій так, щоб дата з'явилася перед розширенням файлу. Так замість
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')
file_name = $ (basename $ 1. $ file_extension)cp -iv $ 1 $ file_name- $ date_formatted. $ file_extension
Я трохи змінив форматування, але ви можете бачити, що Myles оголошує функцію дати в рядку 1. Проте в рядку 2 він використовує команду "echo" з першим аргументом скрипта, щоб вивести ім'я файлу. Він використовує команду pipe, щоб вивести цей висновок і використовувати його як вхід для наступної частини. Після труби Myles закликає команду “awk”, яка є потужною програмою сканування. Використовуючи -F прапор, він говорить команді, що наступний символ (після пробілу) - це те, що визначатиме "роздільник полів". У цьому випадку це період.
Тепер awk бачить файл з ім'ям “tastyfile.mp3” як складається з двох полів: “tastyfile” та “mp3”. Нарешті, він використовує
'print $ NF'
, щоб відобразити останнє поле. У випадку, якщо у вашому файлі є кілька періодів, отже, awk побачить кілька полів, воно буде відображати лише останнє, що є розширенням файлу.
У рядку 3 він створює нову змінну для імені файлу і використовує команду "basename" для посилання на все в $ 1 окрім розширення файлу. Це робиться за допомогою basename і надає йому $ 1 як аргумент, а потім додає пробіл і розширення файлу. Розширення файлу автоматично додано через змінну, яка посилається на Line 2. Що це буде робити, це зробити
tastyfile.mp3
і перетворити його на
смачнафайл
Потім у останньому рядку, Myles збирає команду, яка виведе все в порядку. Зауважте, що немає посилання на $ 2, другий аргумент для сценарію. Цей сценарій скопіює цей файл у ваш поточний каталог. Чудова робота Самуїла і Майлса!
Запуск скриптів і $ PATH
Ми також згадуємо в нашій статті Основи, що скриптам не дозволяється посилатися як команди за замовчуванням. Тобто вам потрібно вказати шлях до сценарію, щоб запустити його:
./ сценарій
~ / bin / script
Але, розмістивши ваші сценарії в ~ / bin /, ви можете просто ввести їхні імена з будь-якого місця, щоб запустити їх.
Коментатори витратили деякий час на обговорення того, як це було правильно, оскільки жоден сучасний дистрибутив Linux не створює цей каталог за замовчуванням. Крім того, ніхто не додає його до змінної $ PATH за замовчуванням, що є необхідним для того, щоб сценарії виконувалися як команди. Я був трохи здивований, тому що після перевірки моєї змінної $ PATH коментатори мали рацію, але виклик скриптів все ще працював для мене. Я дізнався, чому: багато сучасних дистрибутивів Linux створюють спеціальний файл у домашньому каталозі користувача - .profile.
Цей файл читається bash (якщо у домашньому каталозі користувача немає .bash_profile), а внизу є розділ, який додає папку ~ / bin / до змінної $ PATH, якщо вона існує. Отже, ця таємниця прояснена. Для решти серій я продовжую розміщувати сценарії в каталозі ~ / bin /, оскільки вони є користувальницькими скриптами і повинні мати змогу користуватися користувачами. І, здається, нам дійсно не потрібно обробляти змінну $ PATH вручну, щоб отримати справу.
Повторювані команди з циклами
Давайте потрапимо до одного з найкорисніших інструментів арсеналу geek для вирішення повторюваних завдань: циклів. Сьогодні ми будемо обговорювати «за» петлі.
Основний контур for-loop наступний:
для VARIABLE в LIST; робити
command1
command2
…
commandn
зроблено
VARIABLE може бути будь-якою змінною, хоча найчастіше нижній регістр «i» використовується за умовами. LIST - це список елементів; Ви можете вказати кілька елементів (розділяючи їх пробілом), вказати зовнішній текстовий файл або скористатися зірочкою (*) для позначення будь-якого файлу в поточному каталозі. Команди, що перелічені, мають відступ за умовчанням, тому легше бачити вкладеності - введення циклів у цикли (так що ви можете зациклюватися під час циклу).
Оскільки списки використовують пробіли як роздільники - простір означає переміщення до наступного елемента списку - файли, які мають пробіли в імені, не дуже дружні. Поки будемо працювати з файлами без пробілів. Почнемо з простого скрипта, щоб відобразити назви файлів у поточному каталозі. Створіть новий сценарій у вашій ~ / bin / папці під назвою “loopscript”. Якщо ви не пам'ятаєте, як це зробити (включаючи позначення його як виконуваного файлу та додавання хеш-bang hack), зверніться до нашої статті bash.
У ній введіть наступний код:
для i у пункті 1 пункту 2 пункту 3 пункту 4 пункту 5 пункту 6; робити
луна "$ i"
зроблено
Коли ви запускаєте сценарій, ви повинні просто отримати ці елементи списку як вихідні.
Досить просто, чи не так? Давайте подивимося, що станеться, якщо ми трохи змінимо ситуацію. Змініть сценарій так, щоб він сказав:
для i in *; робити
луна "$ i"
зроблено
Коли ви запускаєте цей скрипт у папці, ви повинні отримати список файлів, які він містить як вихід.
Тепер давайте змінимо команду echo на щось більш корисне - скажімо, команду zip. А саме, ми додамо файли до архіву. І, давайте отримаємо деякі аргументи в суміші!
для i в $ @; робити
архів zip "$ i"
зроблено
Є щось нове! “$ @” Є ярликом для “$ 1 $ 2 $ 3… $ n”. Іншими словами, це повний список всіх аргументів, які ви вказали. Тепер подивіться, що відбувається, коли я запускаю сценарій з декількома вхідними файлами.
Ви можете побачити, які файли знаходяться в моїй папці. Я запустив команду з шістьма аргументами, і кожен файл був доданий до архівованого архіву з ім'ям "archive.zip". Легко, правильно?
Для петель досить чудові. Тепер ви можете виконувати пакетні функції в списках файлів. Наприклад, ви можете скопіювати всі аргументи сценарію в архівований архів, перемістити оригінали в іншу папку і автоматично захистити копію цього поштового файлу на віддалений комп'ютер. Якщо ви налаштуєте ключові файли за допомогою SSH, вам навіть не потрібно буде вводити пароль, і навіть можна сказати скрипту, що після завантаження його буде видалено.!
Використання for-loops дозволяє легко виконувати купу дій для всіх файлів у каталозі. Ви можете складати велику кількість різноманітних команд і використовувати аргументи дуже легко, щоб створити і на-лист, і це лише вершина айсберга..
У вас є якісь пропозиції? Ви зробили корисний скрипт, який використовує цикли? Хочете поділитися своїми думками про серію? Залишіть деякі коментарі та допоможіть іншим новачкам сценаріїв!