Как комментарий Златовласка и ссылки человечества описывают,
shiftпереназначение позиционных параметров ( $1, $2и т.д.) , так что $1берет на старое значение $2,
$2принимает значения $3, и т.д. *
Старое значение $1отбрасывается. ( $0не изменено.) Некоторые причины для этого включают в себя:
- Это позволяет вам легче получить доступ к десятому аргументу (если он есть).
$10не работает - он интерпретируется как $1сцепленный с 0
(и может привести к чему-то вроде Hello0). После shift, десятый аргумент становится $9. (Тем не менее, в большинстве современных оболочек вы можете использовать ${10}.)
- Как демонстрирует Bash Guide для начинающих , его можно использовать для циклического прохождения аргументов. ИМНШО, это неуклюже;
forнамного лучше для этого.
- Как и в вашем примере сценария, он позволяет легко обрабатывать все аргументы одинаково, за исключением нескольких. Например, в вашем скрипте есть
$1и $2текстовые строки, тогда как $3и все остальные параметры являются именами файлов.
Вот как это закончится. Предположим, ваш скрипт называется Patryk_scriptи называется
Patryk_script USSR Russia Treaty1 Atlas2 Pravda3
Скрипт видит
$1 = USSR
$2 = Russia
$3 = Treaty1
$4 = Atlas2
$5 = Pravda3
Оператор ostr="$1"устанавливает переменную ostrв USSR. Первый shiftоператор изменяет позиционные параметры следующим образом:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
Оператор nstr="$1"устанавливает переменную nstrв Russia. Второй shiftоператор изменяет позиционные параметры следующим образом:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
И тогда forизменения цикла USSR( $ostr) в Russia( $nstr) в файлах Treaty1, Atlas2и Pravda3.
Есть несколько проблем со сценарием.
для файла в $ @; делать
Если скрипт вызывается как
Patryk_script Договор СССР-Россия1 "Мировой Атлас2" Правда3
это видит
1 доллар = СССР
$ 2 = Россия
$ 3 = Договор1
$ 4 = Мировой Атлас2
$ 5 = Правда3
но, потому что $@не котируются, пространство в World Atlas2не котируются, и forцикл думает , что имеет четыре файла: Treaty1, World, Atlas2и Pravda3. Это должно быть либо
для файла в "$ @"; делать
(цитировать любые специальные символы в аргументах) или просто
для файла сделать
(что эквивалентно более длинной версии).
eval "sed 's /" $ ostr "/" $ nstr "/ g' $ file"
Нет необходимости, чтобы это было eval, и передача непроверенного пользовательского ввода evalможет быть опасной. Например, если скрипт вызывается как
Patryk_script "'; rm *;'" Россия Договор1 Атлас2 Правда3
это выполнит rm *! Это большая проблема, если скрипт может быть запущен с привилегиями выше, чем у пользователя, который его вызывает; например, если он может быть запущен через sudoили вызван из веб-интерфейса. Вероятно, это не так важно, если вы просто используете его в своем каталоге. Но это можно изменить на
sed "s / $ ostr / $ nstr / g" "$ file"
Это все еще имеет некоторые риски, но они гораздо менее серьезны.
if [ -f $file ], > $file.tmpи mv $file.tmp $file
должны if [ -f "$file" ], > "$file.tmp"и mv "$file.tmp" "$file", соответственно, обрабатывать имена файлов, в которых могут быть пробелы (или другие забавные символы). (Команда eval "sed …также изменяет имена файлов, в которых есть пробелы.)
* shift принимает необязательный аргумент: положительное целое число, указывающее, сколько параметров нужно сместить. По умолчанию один ( 1). Например, shift 4причины $5
становиться $1,
$6становиться $2и так далее. (Обратите внимание, что пример в Руководстве по Bash для начинающих неверен.) И поэтому ваш сценарий может быть изменен, чтобы он
ostr="$1"
nstr="$2"
shift 2
что можно считать более понятным.
Конец Примечание / Предупреждение:
Язык командной строки Windows (пакетный файл) также поддерживает SHIFTкоманду, которая делает в основном то же самое, что и shiftкоманда в оболочках Unix, с одним поразительным отличием, которое я скрою, чтобы не допустить путаницы:
- Подобная команда
SHIFT 4является ошибкой, приводящей к сообщению об ошибке «Недопустимый параметр для команды SHIFT».
SHIFT /nгде nцелое число от 0 до 8, допустимо, но оно не сдвигает время . Это сдвигает один раз, начиная с с п - го аргумента. Таким образом , причины (пятый аргумент) , чтобы стать стать , и так далее, в результате чего аргументы 0 до 3 в одиночку.n SHIFT /4%5%4,
%6%5
pushdиpopd).