Là dấu ngã, `~` được coi là một đường dẫn tương đối?


35

Tôi đang cố gắng trích xuất phần khác nhau của trình cài đặt thư viện Nvidia cuda. Tôi đang sử dụng lệnh sau:

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

Và tôi nhận được thông báo sau:

ERROR: extract: path must be absolute.

Và khi tôi gõ lệnh với địa chỉ nghĩa đen của nhà tôi, nó hoạt động hoàn hảo.

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

Tôi bối rối không nên ~ giống với / home / likewise-open / XXX / username?

Thử nghiệm:

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

và nó hoạt động, nhưng tôi không biết tại sao nó không cho phép ~


2
Liên quan: "Một" tiền tố tilde "bao gồm một ký tự <tilde> không được trích dẫn ở đầu từ, theo sau là tất cả các ký tự đứng trước ký tự đầu tiên"
Braiam

Câu trả lời:


47

Bash chỉ mở rộng a ~ nếu đó là sự khởi đầu của một từ. Bạn có thể thấy điều này giữa các lệnh sau:

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

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

Bash tìm kiếm các ~nhân vật độc lập và ~/cho sự thay thế này. Không có sự kết hợp hoặc phiên bản trích dẫn nào sẽ hoạt động.

$HOMEhoạt động vì sự thay thế biến đổi mạnh mẽ hơn ( $là một ký tự đặc biệt trong khi ~rất ít như vậy):

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

Trong khi chúng ta đang nói về ~, nó thực sự có một vài cách sử dụng thay thế khác:

  • ~+thư mục làm việc hiện tại (đọc từ $PWD)
  • ~-thư mục làm việc trước đó (đọc từ $OLDPWD)

Như với đơn giản ~, những đường dẫn này có thể có các đường dẫn bổ sung được xử lý ở cuối và một lần nữa, chúng phải là tiền tố của một từ hoặc Bash sẽ bỏ qua chúng.

Bạn có thể đọc thêm về điều này trong man bash | less -p ' Tilde'


2
Điều đáng chú ý là zsh không (hoặc đúng hơn có thể được cấu hình để) mở rộng ~sau =quá. Trong số các cải tiến thuận tiện khác, nó có hơn bash.
Jan Hudec

@JanHudec Không - nó phức tạp hơn; Nó không phải là về việc mở rộng sau =; đó là về việc mở rộng khi bắt đầu bên phải pf một phép gán biến. Điều đó làm cho trường hợp của chúng tôi khó hiểu hơn một chút khi nhìn kỹ - xem câu trả lời của tôi. Và zshkhông khác với bashtrong này; Mô tả cho 'zsh' là một chút khó hiểu: info --subnodes zsh | less +/'14.7.4 Notes'(thiếu trang zsh man)
Volker Siegel

1
@VolkerSiegel: zshrất có cấu hình. Trong echo -extract=~/testkết quả zsh của tôi trong -extract=/home/user/test. Nó được kích hoạt bởi MAGIC_EQUAL_SUBSTcác tùy chọn. Bên cạnh đó, tôi có tất cả các trang zsh man tốt.
Jan Hudec

@JanHudec Không có nghi ngờ gì về zshcấu hình - và các cải tiến khác; Tôi đã dự kiến ​​rằng MAGIC_EQUAL_SUBST (được nêu trong 14.7.4) không được đặt theo mặc định và hiếm khi được sử dụng; Bây giờ, nó rõ ràng phù hợp hơn nếu bạn kích hoạt nó nói chung. Sau khi tôi có được phần ví dụ của mình trong tình trạng tốt, điều đó sẽ tạo ra một sự bổ sung tuyệt vời ...
Volker Siegel

@JanHudec Về các trang zsh man, họ đã bị thiếu các gói Ubuntu trong một thời gian, cảm ơn vì gợi ý, không biết rằng đã được sửa; Nhìn vào lỗi, nó đã được sửa chữa không tưởng, nhưng không đáng tin - điều đó giải thích nó!. ( launchpad: tất cả các trang web zsh và các tệp trợ giúp nội tuyến đều bị thiếuAU: zsh man bị mất ... )
Volker Siegel

19

Chỉ cần sửa nó

Lệnh này hiển thị thông báo lỗi "ERROR: extract: path phải tuyệt đối":

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

Lỗi không hữu ích - chương trình đã quá bối rối.
Bạn đã biết lỗi là từ ~, vì nó hoạt động với $HOMEthay thế.

Vấn đề: ~chỉ được thay thế khi bắt đầu một từ.

Ví dụ, điều này hoạt động với dấu ngã:

echo -extract ~/Downloads

Nếu bạn cần cú pháp tùy chọn với =, sử dụng $ HOME thay vì ~là giải pháp sạch nhất;

echo -extract=$HOME/Downloads

Việc luyện tập

Bạn nên biết điều gì:

Có những trường hợp đặc biệt khi ~được mở rộng khi không ở đầu từ: như một phần của phép gán biến, ngay sau dấu =. Điều này là khó hiểu ở đây, tất nhiên.

Trường hợp đặc biệt quan trọng khác nó được sử dụng với các biến như PATH. Trong các bài tập biến, ~cũng được mở rộng sau :, như sau lần đầu tiên =.

$ 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

Ý nghĩa của dấu ngã

Trong một cái vỏ, ~dấu ngã, không thực sự là một con đường. Nó chỉ được thay thế bởi một con đường $HOME, một số lần.

Nó là một cái gì đó giống như một tốc ký, hoặc viết tắt, được cung cấp bởi vỏ.
Nó không thể được sử dụng như một con đường nói chung, vỏ "mở rộng" nó thành một con đường chỉ ở những nơi rất đặc biệt.
Và ngay cả khi nó được mở rộng, nó có thể là một cái gì đó khác ngoài thư mục chính.

  • Nó chỉ được mở rộng ở đầu từ hoặc trong một phép gán biến sau một :hoặc=
  • Nó chỉ được mở rộng nếu nó không nằm trong dấu ngoặc kép
  • Nó chỉ được mở rộng thành $HOMEnếu không có thêm ký tự nào trong từ trước một/

Vấn đề trong dòng lệnh

Theo đó, vấn đề trong lệnh của bạn là dấu ngã trong

-extract=~/Downloads/nvidia_installers

không được mở rộng, vì nó không phải là một trong những trường hợp được liệt kê. Đó là tất cả.

Giải pháp có thể là làm cho dấu ngã thành ký tự không được trích dẫn đầu tiên của từ, không có ký tự nào khác trước từ /đó - đó chỉ là những gì bạn nhận được khi bạn sử dụng một tùy chọn có khoảng trắng trước đối số tùy chọn:

-extract ~/Downloads/nvidia_installers

Một giải pháp khác là sử dụng $HOMEthay thế. Trong một kịch bản, đó thường là sự lựa chọn tốt hơn.

-extract=$HOME/Downloads/nvidia_installers

Thông báo lỗi

Nhưng làm thế nào để thông báo lỗi
"ERROR: extract: path must be absolute."?
phù hợp với tất cả điều này?

Chúng tôi biết rằng dấu ngã không được mở rộng. Điều đó có nghĩa là chương trình có văn bản đối số bao gồm ~, nhưng không có /home/auserđường dẫn. Con đường đó là ~/Downloads/nvidia_installers- nhưng bây giờ không có vỏ, nên dấu ngã không có ý nghĩa đặc biệt. Nó chỉ là một tên thư mục bình thường. Và như mọi đường dẫn khác của biểu mẫu foo/bar/baz, nó là một đường dẫn tương đối

Công dụng khác

Nếu có các ký tự sau ~, như trong ~alice- với tất cả các quy tắc khác ở trên áp dụng - và có một tên người dùng alice, được mở rộng sang thư mục chính alicethay vào đó, nói home/alice.
Ngoài ra, nếu bạn bob, ~sẽ mở rộng /home/bob~bobsẽ mở rộng tương tự.

Các biến thể ~+được mở rộng đến thư mục hiện tại,$PWD

Để tham khảo thư mục trước, nơi bạn ở trước cái cuối cùng cd, bạn có thể sử dụng ~-, được mở rộng thành $OLDPWD.

Nếu bạn sử dụng pushdpopd, thay vì cd, bạn sẽ biết rằng ngăn xếp thư mục có thể được truy cập như thế nào ~-2.

Chi tiết

Tất cả các trường hợp ~được mở rộng thành một đường dẫn đều được xử lý bằng vỏ . Đối với các chương trình khác, ~chỉ là một ký tự tên tệp bình thường.

Đối với các định nghĩa chính xác bên trong vỏ, đây là phần có liên quan của Lưu ý cách thay thế bằng chỉ là một trường hợp đặc biệt của nhiều trường hợp: "Nếu tên đăng nhập này là chuỗi rỗng, dấu ngã được thay thế bằng giá trị của tham số vỏ CHỦ. " :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.

3

~không phải là một con đường cho mỗi se. Đó là một nhân vật được đối xử đặc biệt từ trình bao trong đó ~hoặc ~/có nghĩa là "thay thế bằng đường dẫn thư mục chính của người dùng hiện tại". ~usernamecó nghĩa là "thay thế bằng đường dẫn thư mục nhà của tên người dùng".

Bởi vì nó không phải là một đường dẫn, nó chỉ được nhận ra ở một số vị trí nhất định trong lệnh (là ký tự đầu tiên của mã thông báo phân tách không gian mới).

Khi mở rộng, nó thay thế bằng một đường dẫn tuyệt đối.

Sử dụng $HOMEcông việc vì HOME chỉ là một biến được thiết lập bởi shell và tuân theo các quy tắc shell thông thường để thay thế biến (nó xảy ra trước khi đầu vào được phân chia trên khoảng trắng và được thực thi).


1

Bạn nói đúng. ~ / Tải xuống giống như / home / tên người dùng / Tải xuống.

Một số trình cài đặt và trích xuất chỉ rất kén chọn về nơi cần đặt mọi thứ. Tôi nghĩ rằng đó có thể là do nó ghi nhật ký filepath và nhật ký sẽ không chấp nhận ~ trong một đường dẫn được chấp nhận.

Tôi chỉ quen với việc gõ vào / home / tên người dùng thay thế. :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.