Jak opisano komentarz złotowłosa i odniesienia ludzkości,
shift
ponownie przypisuje parametry pozycyjne ( $1
, $2
itp.), Aby $1
nabiera starej wartości $2
,
$2
przyjmuje wartość $3
itp. *
Stara wartość $1
jest odrzucana. ( $0
nie ulega zmianie). Oto niektóre powody:
- Umożliwia łatwiejszy dostęp do dziesiątego argumentu (jeśli taki istnieje).
$10
nie działa - jest interpretowane jako $1
połączone z 0
(i dlatego może wytworzyć coś takiego Hello0
). Po a shift
następuje dziesiąty argument $9
. (Jednak w większości nowoczesnych powłok możesz użyć ${10}
.)
- Jak pokazuje Przewodnik Bash dla początkujących , można go używać do przechodzenia między argumentami. IMNSHO, to jest niezdarne;
for
jest do tego znacznie lepszy.
- Podobnie jak w przykładowym skrypcie, ułatwia przetwarzanie wszystkich argumentów w ten sam sposób, z wyjątkiem kilku. Na przykład w skrypcie
$1
i $2
są ciągami tekstowymi, a $3
wszystkie inne parametry są nazwami plików.
Oto jak to się gra. Załóżmy, że twój skrypt jest wywoływany Patryk_script
i nazywa się jako
Patryk_script USSR Russia Treaty1 Atlas2 Pravda3
Skrypt widzi
$1 = USSR
$2 = Russia
$3 = Treaty1
$4 = Atlas2
$5 = Pravda3
Instrukcja ostr="$1"
ustawia zmienną ostr
na USSR
. Pierwsza shift
instrukcja zmienia parametry pozycyjne w następujący sposób:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
Instrukcja nstr="$1"
ustawia zmienną nstr
na Russia
. Druga shift
instrukcja zmienia parametry pozycyjne w następujący sposób:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
A następnie for
zmiany loop USSR
( $ostr
) do Russia
( $nstr
) w plikach Treaty1
, Atlas2
oraz Pravda3
.
Istnieje kilka problemów ze skryptem.
dla pliku w $ @; zrobić
Jeśli skrypt zostanie wywołany jako
Patryk_script ZSRR Rosja Traktat1 „Atlas świata2” Prawda3
to widzi
1 USD = ZSRR
2 USD = Rosja
3 USD = Traktat 1
4 USD = Atlas Świata 2
5 USD = Pravda3
ale, ponieważ $@
nie jest cytowany, przestrzeń w World Atlas2
nie jest cytowany, a for
pętla myśli, że ma cztery pliki: Treaty1
, World
, Atlas2
i Pravda3
. Tak powinno być
dla pliku w „$ @”; zrobić
(aby zacytować dowolne znaki specjalne w argumentach) lub po prostu
do pliku do
(co odpowiada dłuższej wersji).
eval "sed 's /" $ ostr "/" $ nstr "/ g' $ file"
Nie ma takiej potrzeby eval
, a przekazywanie niepotwierdzonych danych wejściowych do użytkownika eval
może być niebezpieczne. Na przykład, jeśli skrypt jest wywoływany jako
Patryk_script "'; rm *;'" Rosja Traktat1 Atlas2 Prawda3
wykona się rm *
! Jest to duży problem, jeśli skrypt można uruchomić z uprawnieniami wyższymi niż uprawnienia użytkownika, który go wywołuje; np. jeśli można go uruchomić sudo
lub wywołać z interfejsu sieciowego. Prawdopodobnie nie jest to tak ważne, jeśli po prostu używasz go jako siebie, w swoim katalogu. Ale można to zmienić na
sed "s / $ ostr / $ nstr / g" "$ file"
Wciąż wiąże się to z pewnym ryzykiem, ale są one znacznie mniej dotkliwe.
if [ -f $file ]
, > $file.tmp
I mv $file.tmp $file
powinna być if [ -f "$file" ]
, > "$file.tmp"
i mv "$file.tmp" "$file"
, odpowiednio, do obsługi nazw plików, które mogą mieć spacji (lub innych znaków śmieszne) w nich. ( eval "sed …
Polecenie zmienia także nazwy plików ze spacjami).
* shift
przyjmuje opcjonalny argument: dodatnia liczba całkowita, która określa liczbę parametrów do przesunięcia. Domyślna wartość to jeden ( 1
). Na przykład shift 4
powoduje , że $5
się staje $1
,
$6
staje się $2
itd. (Zauważ, że przykład w Bash Guide dla początkujących jest błędny.) Tak więc twój skrypt może zostać zmodyfikowany tak, by powiedział
ostr="$1"
nstr="$2"
shift 2
co można uznać za bardziej jasne.
Uwaga końcowa / ostrzeżenie:
Język wiersza poleceń systemu Windows (plik wsadowy) obsługuje także SHIFT
polecenie, które działa w zasadzie tak samo jak shift
polecenie w powłokach uniksowych, z jedną uderzającą różnicą, którą ukryję, aby zapobiec pomyłkom ludzi:
- Polecenie podobne
SHIFT 4
jest błędem, co powoduje wyświetlenie komunikatu o błędzie „Nieprawidłowy parametr polecenia SHIFT”.
SHIFT /n
, gdzie n
jest liczbą całkowitą od 0 do 8, jest poprawna - ale nie zmienia czasów . Przesuwa się raz, zaczynając od n- tego argumentu. To powoduje, że (piąty argument) staje się itd., Pozostawiając argumenty od 0 do 3 w spokoju.n
SHIFT /4
%5
%4,
%6
%5
pushd
ipopd
).