Выполниться :map N
. Это должно сказать Вам что N
отображается на.
Править: Поскольку @ChrisJohnsen указывает в комментарии на это, :verbose map N
на самом деле получит Вас новый сценарий, который устанавливает отображение.
shift
- встроенный bash
, который удаляет аргументы из начала списка аргументов. Учитывая, что 3 аргумента, представленные в сценарии, доступны в 1
, 2
, 3
, то обращение к сдвигу
сделает 2
новым 1
аргументом.
Сдвиг 2
будет сдвинут на два, в результате чего новый $1
будет равен старому $3
.
Для дополнительной информации смотрите здесь:
Как описывает комментарий Златовласка и ссылки человечества,
shift
переназначает параметры позиции ($1
, $2
и т.д.).
так что $1
принимает старое значение $2
,
$2
принимает значение $3
и т.д. *
Старое значение $1
отбрасывается. ($0
не меняется.)
Некоторые причины для этого включают:
$10
не работает - он интерпретируется как $1
, связанный с 0
.
(и так может быть произведено что-то вроде Hello0
).
После сдвига сдвига
десятым аргументом становится $9
.
(Однако, в большинстве современных оболочек вы можете использовать ${10}
.) для
гораздо лучше. 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
.
Первое утверждение сдвига
изменяет параметры позиции следующим образом:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
утверждение nstr="$1"
устанавливает переменную nstr
на Russia
.
Второе утверждение сдвига
меняет параметры позиции следующим образом:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
А затем в цикле для
меняется СССР
($ostr
) на Россия
($nstr
)
в файлах Договора1
, Атласа2
и Pravda3
.
Есть несколько проблем со сценарием.
для файла в $@; do
Если сценарий вызывается как
Patryk_script USSR Russia Treaty1 "World Atlas2" Pravda3
он видит
$1 = СССР 2 доллара США = Россия 3 = Договор1 $4 = Всемирный атлас2 $5 = Pravda3
, но, поскольку $@
не цитируется, пробел в World Atlas2
не цитируется,
и цикл для
думает, что у него есть четыре файла: Treaty1
, World
, Atlas2
,
и Pravda3
.
Это должно быть либо
для файла в "$@"; do
(для цитирования любых специальных символов в аргументах) или просто
для файла do
(что эквивалентно более длинной версии).
eval "sed 's/"$ostr"/"$nstr"/g' $file"
Нет необходимости в том, чтобы это был eval
,
и передача неконтролируемого пользовательского ввода в систему eval
может быть опасной.
Например, если скрипт вызывается как
Patryk_script "'; rm *;". Российский договор1 Атлас2 Правда3
выполнит rm *
!
Это большая проблема, если скрипт может быть запущен.
с привилегиями выше, чем у пользователя, который на нее ссылается;
например, если его можно запустить через sudo
или вызвать из веб-интерфейса.
Вероятно, это не так важно, если вы просто используете его как самого себя,
в вашем каталоге.
Но его можно изменить на
sed "s/$ostr/$nstr/g" "$file"
Это все еще имеет некоторые риски, но они гораздо менее серьезные.
если [ -f $file ]
, > $file.tmp
и mv $file.tmp $file
.
должно быть , если [ -f "$file" ]
, > "$file.tmp"
и mv "$file.tmp" "$file"
,
соответственно, для обработки имён файлов
в которых могут быть пробелы (или другие забавные персонажи).
(Команда eval "sed ...
" также искажает имена файлов, в которых есть пробелы)
* shift
принимает необязательный аргумент:
положительное целое число, определяющее, сколько параметров нужно сдвинуть.
По умолчанию это единица (1
).
Например, сдвиг 4
вызывает $5
.
чтобы стать 1
,
$6
, чтобы стать $2
, и так далее.
(Обратите внимание, что пример в Bash Guide for Beginners является неверным).
И поэтому ваш скрипт может быть модифицирован, чтобы сказать
ostr="$1"
nstr="$2"
shift 2
, что можно считать более понятным.
End Note / Предупреждение:
Язык командной строки Windows (пакетный файл)
также поддерживает команду SHIFT
,
который делает в основном то же самое, что и команда shift
в оболочках Unix,
с одной поразительной разницей,
которую я спрячу, чтобы не запутать людей:
- Команда вроде
SHIFT 4
- ошибка, с сообщением об ошибке "Недействительный параметр к команде SHIFT".SHIFT /n
, гдеn
- целое число от 0 до 8, является действительным - но не смещаетсяn
times. Он смещается один раз, начиная с аргумента n. Таким образом,SHIFT /4
приводит к тому, что%5
(пятый аргумент) становится%4,
.%6
становится%5
, и так далее, оставляя аргументы с 0 по 3.
shift
обрабатывать аргументы командной строки как очередь FIFO, это элемент popleft каждый раз, когда он вызывается.
array = [a, b, c]
shift equivalent to
array.popleft
[b, c]
$1, $2,$3 can be interpreted as index of the array.
$# is the length of array