Использование контурной петли для переменной окружения
Я пытаюсь написать код, который перемещает файлы в каталог .junk, используя встроенные переменные среды. Моя цель состоит в том, что все, что пользователь должен будет сделать, это ввести sh junk filename1 filename2 filename3 … и скрипт будет использовать $ 1, $ 2, $ 3 … для перемещения файлов. К сожалению, я не могу полностью заставить контур счетчика работать правильно.
#!/bin/s if [ $# = 0 ] then echo "Usage: junk -l | -p | { filename }*" elif [ $1 = "-l" ] && [ $HOME/.junk ] then ls $HOME/.junk elif [ $1 = "-p" ] && [ $HOME/.junk ] then rm -r $HOME/.junk elif [ $1 = "$@" ] && [ $HOME/.junk ] then echo $# i=1 s="$" while [ $i -le $# ] do echo $s$i mv $s$i .junk/$i i=$(($i+1)) done fi
- Как добавить заголовок лицензии рекурсивно для всех файлов .h и .cpp в каталоге
- Использование параметров в скрипте
- Могу ли я помещать диапазоны в параметры?
- Почему мой сценарий оболочки задыхается от пробелов или других специальных символов?
- Git Bash для Ubuntu / Linux и Windows требует перезагрузки ssh-agent
2 Solutions collect form web for “Использование контурной петли для переменной окружения”
Некоторые непосредственные проблемы:
- Используйте
getopts
для обработки аргументов или есть причина, почему нет. - Если скрипту задано более одного аргумента,
"$@"
в третьемelif
взорвет его. - Используйте
for f in "$@"
циклеfor f in "$@"
вместо цикла while.
Зачем?
- Что произойдет, если вы
sh junk --help
… или еще один интересный вариантmv
? - QED
- Упрощенный => Лучше
#!/bin/sh junkdir="$HOME/.junk" do_list=0 do_purge=0 while getopts 'lp' opt; do case "$opt" in l) do_list=1 ;; p) do_purge=1 ;; *) printf 'Usage: %s [-l|-p] [ name ... ]\n' "$0" >&2 exit 1 ;; esac done shift "$(( OPTIND - 1 ))" if [ "$do_list" -ne 0 ]; then printf 'Current junk in "%s":\n' "$junkdir" ls -l "$junkdir" fi if [ "$do_purge" -ne 0 ]; then printf 'Emptying junk directory "%s"\n' "$junkdir" rm -rf "$junkdir" mkdir "$junkdir" fi if [ ! -d "$junkdir" ]; then printf '%s: Missing junk directory "%s"\n' "$0" "$junkdir" >&2 printf '%s: Re-run with -p to create it\n' "$0" exit 1 fi if [ "$#" -eq 0 ]; then exit fi echo 'Junking the following things:' printf '%s\n' "$@" mv "$@" "$junkdir"
Этот скрипт реализует то, что вы пытаетесь сделать. Он использует getopts
для разбора флагов командной строки -l
и / или -d
.
Я устанавливаю do_list
и do_remove
в цикле while, который анализирует параметр командной строки, потому что я хочу контролировать порядок, в котором ls
и rm
имеют место дальше. Если пользователь использует -lp
или -pl
я хочу, чтобы они увидели содержимое каталога нежелательной -pl
до его удаления.
Удаление каталога нежелательной -p
с помощью -p
также воссоздает его. Я делаю это с помощью rm -rf
за которым следует mkdir
для простоты.
После цикла синтаксического анализа командной строки я корректирую параметры позиционирования, чтобы они содержали только аргументы без параметров (имена файлов и / или каталогов).
Если нет позиционных аргументов ( $#
равно нулю), я не пытаюсь запустить mv
для перемещения файлов в каталог мусора.