Какова цель использовать, переключают сценарии оболочки на нижний регистр?

Выполниться :map N. Это должно сказать Вам что N отображается на.

Править: Поскольку @ChrisJohnsen указывает в комментарии на это, :verbose map N на самом деле получит Вас новый сценарий, который устанавливает отображение.

128
09.03.2019, 20:43
3 ответа

shift - встроенный bash, который удаляет аргументы из начала списка аргументов. Учитывая, что 3 аргумента, представленные в сценарии, доступны в 1, 2, 3, то обращение к сдвигу сделает 2 новым 1 аргументом. Сдвиг 2 будет сдвинут на два, в результате чего новый $1 будет равен старому $3 . Для дополнительной информации смотрите здесь:

151
27.01.2020, 19:29

Как описывает комментарий Златовласка и ссылки человечества, shift переназначает параметры позиции ($1, $2 и т.д.). так что $1 принимает старое значение $2, $2 принимает значение $3 и т.д. *  Старое значение $1 отбрасывается.  ($0 не меняется.)  Некоторые причины для этого включают:

  • Это позволяет легче получить доступ к десятому аргументу (если он есть).  $10 не работает - он интерпретируется как $1, связанный с 0. (и так может быть произведено что-то вроде Hello0).  После сдвига сдвига десятым аргументом становится $9.  (Однако, в большинстве современных оболочек вы можете использовать ${10}.)
  • Как показывает Bash Guide for Beginners, он может быть использован для перебора аргументов.  IMNSHO, это неуклюже; для гораздо лучше.
  • Как и в вашем примере скрипта, это позволяет легко обрабатывать все аргументы одинаковым образом, за исключением нескольких.  Например, в вашем скрипте, 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.



Есть несколько проблем со сценарием.

  1. для файла в $@; 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

    (что эквивалентно более длинной версии).

  2. eval "sed 's/"$ostr"/"$nstr"/g' $file"

    Нет необходимости в том, чтобы это был eval, и передача неконтролируемого пользовательского ввода в систему eval может быть опасной.  Например, если скрипт вызывается как

    Patryk_script "'; rm *;". Российский договор1 Атлас2 Правда3

    выполнит rm *!  Это большая проблема, если скрипт может быть запущен. с привилегиями выше, чем у пользователя, который на нее ссылается; например, если его можно запустить через sudo или вызвать из веб-интерфейса.  Вероятно, это не так важно, если вы просто используете его как самого себя, в вашем каталоге.  Но его можно изменить на

    sed "s/$ostr/$nstr/g" "$file"

    Это все еще имеет некоторые риски, но они гораздо менее серьезные.

  3. если [ -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.
36
27.01.2020, 19:29

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
3
27.01.2020, 19:29

Теги

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