Розгорніть подалі тести
По суті, оболонка - це якась макро мова, або, принаймні, гібридна чи якась. Кожен командний рядок може бути розбитий на дві частини: частину розбору / введення та частину розширення / виведення.
Перша частина - це те, на що більшість людей зосереджується, тому що це найпростіше: ти бачиш, що отримуєш. Друга частина - це те, що багато хто уникає, навіть намагаючись зрозуміти дуже добре, і тому люди кажуть, що таке, як eval
зло, і завжди цитують ваші розширення - люди хочуть, щоб результат першої частини дорівнював першому. Це нормально - але це призводить до зайвих довгих гілок коду та тонни сторонніх тестувань.
Розширення - це самоперевірка . Ці ${param[[:]#%+-=?]word}
форми більш ніж достатньо , щоб перевірити вміст параметра, є вкладеністю, і все вони засновані навколо оцінки для NUL - який є те , що більшість людей чекають тестів в будь-якому випадку. +
може бути особливо зручним в петлях:
r()while IFS= read -r r&&"${r:+set}" -- "$@" "${r:=$*}";do :;done 2>&-
IFS=x
printf %s\\n some lines\ of input here '' some more|{ r;echo "$r"; }
somexlines ofxinputxhere
... поки read
тягне не пусті рядки, "${r:+set}"
розширюється "set"
і позиції $r
додаються. Але коли порожній рядок read
, $r
порожній і "${r:+set}"
розширюється ""
- що є неправильною командою. Але оскільки командний рядок розширений перед тим, ""
як шукати нульову команду, "${r:=$*}"
приймає також значення всіх позицій, об'єднаних у перший байт $IFS
. r()
може бути викликаний ще раз у |{
складеній команді ;}
w / інше значення для $IFS
отримання наступного вхідного абзацу, оскільки це незаконно read
буферизація оболонки за межами наступної \n
лінії введення.
sh
і яка оболонка дозволяє цейfor
синтаксис? це прямо дозволяється вzsh
.