Как комментарий Златовласка и ссылки человечества описывают,
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
).