Dlaczego polecenie mkdir kończy się niepowodzeniem: „Brak takiego pliku lub katalogu”?
#!/bin/bash
set -e
BIN_DIR="~/bin/"
if [ ! -d "$BIN_DIR" ]; then
mkdir "$BIN_DIR"
fi
Dlaczego polecenie mkdir kończy się niepowodzeniem: „Brak takiego pliku lub katalogu”?
#!/bin/bash
set -e
BIN_DIR="~/bin/"
if [ ! -d "$BIN_DIR" ]; then
mkdir "$BIN_DIR"
fi
Odpowiedzi:
Pojawia się komunikat o błędzie, ponieważ ~
zacytowano tyldę , jak opisano w odpowiedzi Zanny . Jeśli chcesz użyć ~
, odpowiednią częścią skryptu powinna być:
BIN_DIR=~/bin/
Jeśli z jakiegokolwiek powodu chcesz zacytować ciąg, możesz użyć zmiennej środowiskowej $HOME
:
BIN_DIR="$HOME/bin/"
Moim zdaniem drugim podejściem jest lepsza praktyka.
~
skryptów. działa dokładnie tak samo, jak w wierszu poleceń. Problem polega na tym, że cytowanie blokuje ekspansję tyldy, jak wyjaśniono w odpowiedzi Zanny .
$HOME
w skryptach jest dobrym pomysłem.
$HOME
niż używać rozszerzenia tyldy? Jedynym wyjaśnieniem, które podałeś, jest powiedzenie: „to lepszy pomysł, ponieważ powinieneś mniej uważać”. Nie mam pojęcia co to znaczy. Czy możesz to wyjaśnić w edycji? Bez tego nic nie potwierdza twojej odpowiedzi, więc na pewno do niej należy. Tyldy został wymagane przez POSIX na jakiś czas teraz i linia hashbang skrypt jest #!/bin/bash
tak przypuszczam przenośność nie jest powód.
To nie działa, ponieważ ~
jest cytowane. Cudzysłowy "
tłumić tyldy ekspansji . Nie ma katalogu o dosłownej nazwie ~/bin
. Jak wyjaśniono w man bash
(moje podkreślenie):
Rozszerzenie Tilde
Jeśli słowo zaczyna się od nienotowanego znaku tyldy ( `~ '), wszystkie znaki poprzedzające pierwszy nienotowanych ukośnik (lub wszystkie znaki, gdy nie ma nienotowanych ukośnik) są uważane za przedrostkiem tyldy. Jeśli nie zacytowano żadnego ze znaków w prefiksie tyldy, znaki w prefiksie tyldy po tyldie są traktowane jako możliwa nazwa logowania. Jeśli ta nazwa logowania jest łańcuchem zerowym, tylda jest zastępowana wartością parametru powłoki HOME. Jeśli HOME jest wyłączone, katalog domowy użytkownika wykonującego powłokę jest zastępowany. W przeciwnym razie przedrostek tyldy zostanie zastąpiony katalogiem domowym powiązanym z określoną nazwą logowania.
Możesz usunąć cudzysłowy , ponieważ ~
jest to jedyny znak na ścieżce ~/bin
, który spowoduje, że powłoka wykona rozwinięcie, a my chcemy rozwinięcia w tym przypadku. Powłoka nie będzie wykonywać żadnych dalszych rozszerzeń na skutek ekspansji tyldy, przynajmniej w Bash 4 , który wszystkie obecne lub zdalnie ostatnich wydaniach Ubuntu mają . Nawet jeśli katalog domowy zawiera nietypowe znaki, takie jak spacje, jest w porządku.
Albo można użyć $HOME
zamiast z ~
, ponieważ ekspansja parametr nie jest tłumione przez cudzysłów, tylko przez pojedynczych cudzysłowach . Podwójne cudzysłowy nie zapewniają, że rozszerzona wartość nie jest sama w sobie przedmiotem dalszych rozwinięć, więc podział na słowa lub rozszerzenie nazwy pliku nie nastąpi. $HOME
Działa więc nawet z dziwnie nazwanymi katalogami domowymi, o ile zachowasz podwójne cudzysłowy.
cd '~'
jest -bash: cd: ~: No such file or directory
.
~
nie jest częścią rozszerzenia parametru.