Розгорніть подалі тести
По суті, оболонка - це якась макро мова, або, принаймні, гібридна чи якась. Кожен командний рядок може бути розбитий на дві частини: частину розбору / введення та частину розширення / виведення.
Перша частина - це те, на що більшість людей зосереджується, тому що це найпростіше: ти бачиш, що отримуєш. Друга частина - це те, що багато хто уникає, навіть намагаючись зрозуміти дуже добре, і тому люди кажуть, що таке, як 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.