Есть ли способ изменить массив $@ в сценарии оболочки POSIX

Если вы все еще хотите установить Linux на свой Chromebook , я предлагаю вам заглянуть в этот блог:

mrchromebox.tech/ #fwscript

Затем в режиме разработчика откройте оболочку:CTRL+ALT+T и введите shell

Загрузите и выполните скрипт для обновления прошивки :

cd; curl -LO https://mrchromebox.tech/firmware-util.sh && sudo bash firmware-util.sh

По завершении этого шага загрузите образ(ISO )ОС Linux, которую вы хотите установить на Chromebook. Я бы взял Gallium OS , так как она была специально разработана для хромбуков .

Затем с помощью Etcher или Rufus запишите его на USB-накопитель или SD-карту.

Наконец, вы можете перезагрузиться с подключенной USB / SD-картой и нажать CTRL -L. Это заставит вас переключиться на галлиевую ОС. Если вы хотите загрузиться в Chrome OS, просто используйте CTRL -D при запуске.

Если вы хотите удалить ОС Gallium, просто используйте флэш-накопитель для восстановления и перезагрузите Chromebook.

0
07.03.2020, 10:06
2 ответа

Ваш исходный код:

for file in "$@"; do
    [ -L "$file" ] && file=$(readlink -f -- "$file")
done

Проблема в том, что настройка fileв цикле не влияет на содержимое списка позиционных параметров.

Вместо этого вы можете использовать

for file in "$@"; do
    [ -L "$file" ] && file=$(readlink -f -- "$file")
    set -- "$@" "$file"
    shift
done

Теперь мы смещаем записи с начала "$@"одну за другой и добавляем потенциально измененные записи в конец списка. Изменение $@в цикле forнад $@не является проблемой, поскольку циклы forвсегда перебирают статический список, т. е. список, который повторяется, оценивается только один раз в начале цикла.

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

Цикл также можно записать в немного более короткой форме (вызов readlinkдля каждого элемента ),

for dummy do
    set -- "$@" "$(readlink -f -- "$1")"
    shift
done

Здесь используется readlinkв соответствии с вашим вопросом, хотя это и не утилита POSIX.

Обратите внимание, что если выводreadlinkзаканчивается одной или несколькими символами новой строки(помимо той, которая добавлена ​​для завершения последней строки вывода ), они будут удалены. Это следствие подстановки команды. Если это проблема, искусственно добавьте завершающий символ в подстановку команды, а затем удалите его, как mosvyпредлагает в комментариях :

.
for file do
    [ -L "$file" ] && file=$(readlink -f -- "$file"; echo x)
    set -- "$@" "${file%x}"
    shift
done
2
28.04.2021, 23:21

Обратите внимание, что ни readlink, ни realpathне являются командами POSIX. Инструментарий командной строки POSIX не имеетrealpath()-подобного API. Здесь вместо readlink(, для которого существуют различные несовместимые реализации ), вы можете использовать zsh, который также имеет встроеннуюrealpath()-функциональность, подобную -, с модификатором :P. В вашем скрипте sh:

eval "set -- $(zsh -c 'print -r ${(qq)argv:P}' zsh "$@")"

Хотя вы могли бы также написать свой сценарий в zshв первую очередь, где он будет просто:

argv=($argv:P)

Или, если python3более доступен, чем zsh:

eval "set -- $(
  LC_ALL=C python3 -c '
import sys, os, shlex
print(" ".join(map(shlex.quote, map(os.path.realpath, sys.argv[1:]))))' "$@")"
0
28.04.2021, 23:21

Теги

Похожие вопросы