Що робить $ {0% / *} у скриптах оболонки?


17

Вибачте, якщо це дурне питання, але я про це шукав без успіху.

Що саме робить другий рядок?

#!/bin/sh
cd ${0%/*} || exit 1

Я знаю, перший - шебанг, другий намагається змінити каталог, але заплутаною є частина ${0%/*}.

Чи можете ви мені пояснити, що другий рядок?


2
Як пояснив Андреа у відповіді, $ {0% / *} перекладається на шлях до каталогу, який має префікс до імені сценарію, при цьому викликаючи його. Альтернативою є використання вбудованої dirnameкоманди типу$(dirname $0)
завждинавчання

@alwayslearning: Яку вбудовану оболонку та оболонку ви використовуєте dirname? Це, звичайно, не в Bash v4.3.11, що є оболонкою за замовчуванням у Ubuntu Trusty.
Девід Фоерстер

Вибачте за плутанину, щойно перевірив, dirnameчи не вбудована оболонка.
завждинавчання

Відповіді:


27

${0}- це перший аргумент сценарію, тобто ім'я або шлях сценарію. Якщо запустити сценарій як path/to/script.sh, то ${0}буде саме цей рядок: path/to/script.sh.

%/*Частина змінює значення ${0}. Це означає: приймати всі символи, поки не /піде ім'я файлу. У прикладі вище, ${0%/*}буде path/to.

Ви можете бачити це в дії на своїй оболонці:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Sh підтримує багато інших видів "заміни параметрів". Ось, наприклад, як взяти ім’я файлу замість шляху:

$ echo "${x##*/}"
script.sh

Загалом, %і %%суфікси смуги, а префікси у той час як #і ##смуги. Ви можете прочитати докладніше про підміну параметрів .


2
Цей "|| вихід 1" видається непотрібним: якщо змінити dir $ буде неможливо? дорівнює 1.
Йозеф Климук

2
Було б добре згадати, що конструкція в документі задокументована як "Видалити узгоджувальний префікс / суфікс". Також хороший спосіб запам'ятати, який полягає в тому, що # є зсувом 3 ( зліва від $),% - це зсувом 5 ( праворуч від $), принаймні, на клавіатурі США.
chexum

1
@JosefKlimuk: || exit 1 може знадобитися, оскільки cdможе вийти зі статусом 2, а не 1, помилково. Однак я погоджуюся, що це не дуже корисно (зазвичай програми не цікавляться певними статусами виходу). Можливо, це частина більшого сценарію?
Андреа Корбелліні

1
@AndreaCorbellini Напевно правильно. Насправді єдиний спосіб, коли він взагалі може бути корисним - це частина більшого сценарію. Сценарій, який просто змінює поточний каталог, не має ефекту, оскільки він впливає лише на оболонку, на якій працює цей один сценарій. Батьківський процес ніколи цього не бачить.
hvd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.