Apakah tilde, `~` dianggap sebagai jalur relatif?

35

Saya mencoba untuk mengekstrak bagian berbeda dari installer perpustakaan Nvidia cuda. Saya menggunakan perintah berikut:

mkdir ~/Downloads/nvidia_installers
./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers

Dan saya mendapatkan pesan berikut:

ERROR: extract: path must be absolute.

Dan ketika saya mengetik perintah dengan alamat literal rumah saya, itu berfungsi dengan baik.

./cuda_6.5.14_linux_64.run -extract=/home/likewise-open/XXX/username/Downloads/nvidia_installers

Saya tidak boleh bingung ~ sama dengan / home / like-open / XXX / username?

Diuji:

./cuda_6.5.14_linux_64.run -extract=$HOME/Downloads/nvidia_installers

dan itu berhasil, tetapi saya tidak tahu mengapa itu tidak memungkinkan ~

Regan
sumber
2
Terkait: "A" tilde-prefix "terdiri dari karakter <tilde> yang tidak dikutip di awal kata, diikuti oleh semua karakter sebelum tanda
kutip

Jawaban:

47

Bash hanya mengembang ~ jika itu awal kata. Anda dapat melihat ini di antara perintah berikut:

$ echo -extract=~/test
-extract=~/test

oli@bert:~$ echo -extract ~/test
-extract /home/oli/test

Bash mencari ~karakter mandiri dan ~/substitusi ini. Tidak ada kombinasi lain atau versi yang dikutip akan bekerja.

$HOMEberfungsi karena substitusi variabel lebih kuat ( $ini adalah karakter khusus sedangkan ~sangat kurang begitu):

$ echo Thisisastring${HOME}awrawr
Thisisastring/home/oliawrawr

Sementara kita berbicara tentang ~, itu sebenarnya memiliki beberapa kegunaan substitusi lain:

  • ~+direktori kerja saat ini (baca dari $PWD)
  • ~-direktori kerja sebelumnya (baca dari $OLDPWD)

Seperti biasa ~, ini dapat memiliki jalur tambahan yang ditempel di akhir, dan sekali lagi, ini harus menjadi awalan untuk sebuah kata atau Bash akan mengabaikannya.

Anda dapat membaca lebih lanjut tentang ini di man bash | less -p ' Tilde'

Oli
sumber
2
Perlu dicatat bahwa zsh tidak (atau lebih tepatnya dapat dikonfigurasi untuk) berkembang ~setelahnya =juga. Di antara peningkatan nyaman lainnya yang dimilikinya lebih dari bash.
Jan Hudec
@ JanHudec Tidak - ini lebih rumit; Ini bukan tentang ekspansi setelah =; ini adalah tentang ekspansi pada awal sisi kanan dari penugasan variabel. Itu membuat kasus kami sedikit lebih membingungkan ketika melihat lebih dekat - lihat jawaban saya. Dan zshtidak berbeda bashdengan ini; Deskripsi untuk 'zsh' sedikit samar: info --subnodes zsh | less +/'14.7.4 Notes'(halaman buku zsh hilang)
Volker Siegel
1
@ VolkerSiegel: zshsangat bisa dikonfigurasi. Di echo -extract=~/testhasil zsh saya di -extract=/home/user/test. Ini diaktifkan oleh MAGIC_EQUAL_SUBSTopsi. Sebagai catatan, saya memiliki semua halaman manual zsh dengan baik.
Jan Hudec
@JanHudec Tidak diragukan lagi zshdapat dikonfigurasi - dan peningkatan lainnya; Saya berharap bahwa MAGIC_EQUAL_SUBST (tercakup dalam 14.7.4) tidak disetel secara default, dan jarang digunakan; Sekarang, ini jelas lebih relevan jika Anda mengaktifkannya secara umum. Setelah saya mendapatkan bagian contoh saya dalam kondisi yang baik, itu akan menjadi tambahan yang bagus ...
Volker Siegel
@JanHudec Mengenai halaman manual zsh, mereka hilang dari paket Ubuntu untuk sementara waktu, terima kasih atas petunjuknya, tidak tahu itu sudah diperbaiki; Melihat bug, itu diperbaiki untuk utopis, tetapi tidak dapat dipercaya - itu menjelaskannya !. ( launchpad: semua halaman manual zsh dan file bantuan sebaris tidak ada dan AU: zsh man hilang ... )
Volker Siegel
19

Hanya memperbaikinya

Perintah ini menunjukkan pesan kesalahan "ERROR: extract: path must absolute":

./cuda_6.5.14_linux_64.run -extract=~/Downloads/nvidia_installers

Kesalahan tidak membantu - programnya sudah terlalu bingung.
Anda sudah tahu kesalahan berasal dari ~, karena berfungsi $HOMEsebagai gantinya.

Masalahnya: ~hanya akan diganti pada awal kata.

Misalnya, ini berfungsi dengan tilde:

echo -extract ~/Downloads

Jika Anda memerlukan sintaks opsi =, menggunakan $ HOME dan bukan ~merupakan solusi yang paling bersih;

echo -extract=$HOME/Downloads

Latihan

Apa yang harus Anda ketahui:

Ada kasus khusus di mana ~get diperluas ketika tidak di awal kata: sebagai bagian dari penugasan variabel, langsung setelah= . Yang membingungkan di sini, tentu saja.

Kasus khusus penting lainnya untuk digunakan dengan variabel seperti PATH. Dalam penugasan variabel, ~juga diperluas setelah :, seperti setelah yang pertama =.

$ dir=~ sh -c 'echo D2: $dir'
D2: /home/user
$ sh -c 'echo D2: $dir' dir=~
D2: 
$ echo Dir: $dir
Dir:
$ dir=~; sh -c 'echo D2: $dir'
D2: 
$ echo Dir: $dir
Dir: /home/user
$ sh -c 'echo D2: $dir'; d3=~
D2: 
$ echo d3: $d3
d3: /home/user

Arti dari tilde

Dalam sebuah shell,, ~tilde, sebenarnya bukan jalan. Itu hanya digantikan oleh jalan,$HOME ,, beberapa kali.

Itu adalah sesuatu seperti steno, atau singkatan, yang disediakan oleh shell.
Itu tidak dapat digunakan seperti jalan pada umumnya, shell "memperluas" ke jalan hanya di tempat yang sangat khusus.
Dan bahkan jika itu diperluas, itu bisa ke sesuatu yang lain dari direktori home.

  • Ini hanya diperluas di awal kata , atau dalam penugasan variabel setelah :atau=
  • Hanya diperluas jika itu tidak ada di dalam tanda kutip
  • Hanya diperluas ke $HOMEjika tidak ada karakter lebih lanjut dalam kata sebelum a/

Masalahnya di baris perintah

Menurut ini, masalah dalam perintah Anda adalah bahwa tilde masuk

-extract=~/Downloads/nvidia_installers

tidak diperluas, karena itu bukan salah satu kasus yang terdaftar. Itu saja.

Solusinya bisa menjadikan tilde karakter tanpa tanda kutip pertama dari sebuah kata, tanpa karakter lain sebelum yang berikutnya /- itulah yang Anda dapatkan saat menggunakan opsi dengan spasi sebelum argumen opsi:

-extract ~/Downloads/nvidia_installers

Solusi lain akan digunakan $HOMEsebagai gantinya. Dalam naskah, itu biasanya pilihan yang lebih baik.

-extract=$HOME/Downloads/nvidia_installers

Pesan kesalahan

Tapi bagaimana pesan kesalahannya
"ERROR: extract: path must be absolute."?
cocok dengan semua ini?

Kita tahu bahwa tilde tidak berkembang. Itu berarti program mendapatkan teks argumen termasuk ~, tetapi tanpa /home/auserpath. Jalan itu ~/Downloads/nvidia_installers- tetapi sekarang tidak ada shell, jadi tilde tidak memiliki arti khusus. Itu hanya nama direktori normal. Dan seperti setiap jalur bentuk lainnyafoo/bar/baz , itu adalah jalur relatif

Penggunaan lainnya

Jika ada karakter setelah ~, seperti di ~alice- dengan semua aturan lain di atas berlaku - dan ada nama pengguna alice, yang diperluas ke direktori home alice, katakanlah home/alice.
Juga, jika Anda bob, ~akan memperluas ke /home/bob, dan ~bobakan memperluas ke yang sama.

Varian ~+diperluas ke direktori saat ini,$PWD

Untuk merujuk ke direktori sebelumnya, di mana Anda berada sebelum yang terakhir cd, Anda dapat menggunakan ~-, yang diperluas ke $OLDPWD.

Jika Anda menggunakan pushddan popd, alih-alih cd, Anda sudah akan tahu bahwa tumpukan direktori dapat diakses seperti~-2 .

Detail

Semua case di mana ~diperluas ke path handeled oleh shell . Untuk program lain,~ hanya karakter nama file normal.

Untuk definisi yang tepat di dalam shell, di sini adalah bagian yang relevan dari Catatan bagaimana mengganti dengan hanya satu kasus khusus dari banyak kasus: "Jika nama login ini adalah string nol, tilde diganti dengan nilai parameter shell HOME. " :man bash
~$HOME

Tilde Expansion
    If a word begins with an unquoted tilde character (`~'), all of the charac‐
    ters  preceding the first unquoted slash (or all characters, if there is no
    unquoted slash) are considered a tilde-prefix.  If none of  the  characters
    in  the tilde-prefix are quoted, the characters in the tilde-prefix follow‐
    ing the tilde are treated as a possible login name.  If this login name  is
    the  null string, the tilde is replaced with the value of the shell parame‐
    ter HOME.  If HOME is unset, the home directory of the user  executing  the
    shell is substituted instead.  Otherwise, the tilde-prefix is replaced with
    the home directory associated with the specified login name.

    If the tilde-prefix is a `~+', the value of the shell variable PWD replaces
    the  tilde-prefix.   If  the tilde-prefix is a `~-', the value of the shell
    variable OLDPWD, if it is set, is substituted.  If the characters following
    the tilde in the tilde-prefix consist of a number N, optionally prefixed by
    a `+' or a `-', the tilde-prefix is replaced with the corresponding element
    from  the  directory  stack,  as  it would be displayed by the dirs builtin
    invoked with the tilde-prefix as an argument.  If the characters  following
    the  tilde in the tilde-prefix consist of a number without a leading `+' or
    `-', `+' is assumed.

    If the login name is invalid, or the tilde expansion  fails,  the  word  is
    unchanged.

    Each variable assignment is checked for unquoted tilde-prefixes immediately
    following a : or the first =.  In these cases, tilde expansion is also per‐
    formed.   Consequently, one may use filenames with tildes in assignments to
    PATH, MAILPATH, and CDPATH, and the shell assigns the expanded value.
Volker Siegel
sumber
3

~bukan jalan per se. Ini adalah karakter yang mendapat perlakuan khusus dari shell di mana ~atau ~/berarti "ganti dengan jalur direktori home pengguna saat ini".~usernameberarti "ganti dengan jalur direktori home nama pengguna".

Karena itu bukan jalan, itu hanya dikenali di tempat-tempat tertentu dalam perintah (sebagai karakter pertama dari token pemisah ruang baru).

Ketika diperluas, itu diganti dengan jalur absolut.

Menggunakan $HOMEkarya karena HOME hanya variabel yang diatur oleh shell dan mengikuti aturan shell normal untuk penggantian variabel (itu terjadi sebelum input dibagi pada spasi dan dieksekusi).

Daenyth
sumber
1

Anda benar. ~ / Unduhan sama dengan / home / nama pengguna / Unduhan.

Beberapa installer dan extractors sangat pilih-pilih di mana perlu meletakkan sesuatu. Saya pikir itu mungkin karena log filepath, dan log tidak akan menerima ~ di jalur yang diterima.

Saya terbiasa mengetik / home / username saja. :)

Dan Johansen
sumber