Sự khác biệt giữa $ HOME và ~


31

$HOME~thường đề cập đến điều tương tự. Đó là, chúng là đường dẫn đến thư mục "nhà của người dùng" có dạng chung "/ home / userName".

Khi nào, nếu có, những điều này không đề cập đến cùng một thư mục?


11
Cái ~vỏ phụ thuộc trong khi $ HOME thì không.
Kulfy

Câu trả lời:


45

Cả hai $HOME~trỏ đến cùng một thư mục, thư mục nhà của người dùng hiện tại, nhưng cả hai đều là những thứ rất khác nhau.

  • $HOMElà một biến môi trường , được đặt để chứa thư mục chính của người dùng hiện tại.
  • ~là một biểu tượng mở rộng shell , tức là một trong những biểu tượng được xử lý trước khi lệnh thực tế được thực hiện. ~một mình mở rộng đến giá trị của $ HOME. ~nemomở rộng đến thư mục nhà của người dùng nemo. Biểu tượng mở rộng shell là một ký tự (hoặc cặp ký tự) được xử lý / giải thích bởi shell để xây dựng lệnh thực tế. Một ví dụ khác về biểu tượng mở rộng shell là *, được sử dụng để mở rộng tên tệp.

1
~mở rộng thành $ HOME hoặc% APPDATA% trên Windows. Nếu chúng không được xác định, nó sẽ tìm đường dẫn trong "cơ sở dữ liệu mật khẩu" (thường có nghĩa là /etc/passwd, nhưng có thể là LDAP hoặc một số nguồn dữ liệu khác). Khoảng 20 năm trước, bạn có thể đã được cảnh báo rằng $ HOME có thể không được đặt trên một số máy, trong khi ~được đảm bảo mở rộng sang thứ gì đó.
Mirek Długosz

Sự khác biệt này là đáng chú ý trong các chương trình như make, khi bạn cần biết cái nào trong hai bạn cần
D. Ben Knoble

3
@ MirekDługosz Ít nhất là trên git bash trên Windows, ~mở rộng thành $HOME(bằng $HOMEPATH), không $APPDATA. Và trên cmd.exe, ~không mở rộng.
hyde

1
@vanadi HOMElà một biến môi trường (một khái niệm hệ điều hành, trong ví dụ sh shell được đặt bằng exporthoặc declare -x), không phải là biến shell (định nghĩa phụ thuộc hoàn toàn vào shell, nhưng trong shell sh, nó thường được đặt cùng foo=valuehoặc với setmột vài cái khác cách).
hyde

1
@hyde Tôi nói sai rồi. bash sẽ kiểm tra $ HOME, nếu không được đặt, nó sẽ kiểm tra% APPDATA%, nhưng chỉ trên Windows; nếu nó không được đặt, nó sẽ tra cứu "cơ sở dữ liệu mật khẩu". Xem git.savannah.gnu.org/cgit/bash.git/tree/lib/readline/ Kẻ
Mirek Długosz

17

Một cách chúng khác nhau là cách vỏ Bash chuyển đổi chúng khi được đặt trong "loại dấu ngoặc kép.

Nếu bạn sử dụng echonhư thế này, không có bất kỳ trích dẫn nào, ~$HOMEcó tác dụng tương tự:

$ echo ~
/home/elias
$ echo $HOME
/home/elias

Tuy nhiên, với "dấu ngoặc kép quanh chúng, kết quả khác nhau:

$ echo "~"
~
$ echo "$HOME"
/home/elias

13

~chỉ mở rộng như một phần của tiền tố dấu ngã mà theo định nghĩa phải bắt đầu từ đầu từ. Ngoài ra, vì nó đã từng là một phần của các mẫu hình cầu, ~sẽ không hoạt động bên trong dấu ngoặc kép. Vì vậy, "~"hoặc a~bsẽ dẫn đến một giá trị theo nghĩa đen của ~việc được bảo tồn.

Một ~(hoặc ~theo sau bởi a /) sẽ mở rộng đến nhà của người dùng hiện tại:

$ echo ~/.ssh
/home/user/.ssh

Một ~tiếp theo là một tên người dùng sẽ mở rộng vào thư mục home của người dùng:

$ echo ~root/.ssh
/root/.ssh

A ~theo sau là a +hoặc a -và một số tùy chọn sẽ mở rộng thành các phần tử của ngăn xếp thư mục :

$ cd /etc
$ echo ~+0
/etc

$HOMElà tương đương với một đơn ~, thay vào đó tuân theo các quy tắc cú pháp cho các biến. Ví dụ, nó mở rộng bên trong dấu ngoặc kép, có thể không được đặt và các toán hạng thao tác chuỗi có thể được áp dụng cho nó.


3

Điều này phụ thuộc rất nhiều vào việc mở rộng. Trong bash, ~là một cách thuận tiện để lấy thư mục chính mà không kích hoạt mở rộng tên tệp hoặc tách từ mặc dù không được trích dẫn. Ví dụ:

$ HOME='/*'
$ echo $HOME
/bin /boot /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
$ echo ~
/*

Hoặc là:

$ HOME='/ a b'
$ printf "|%s|\n" $HOME ~
|/|
|a|
|b|
|/ a b|

Vì vậy, nếu bạn đang vật lộn với dấu ngoặc kép vì một lý do nào đó (trong trường hợp đó bạn thực sự nên suy nghĩ lại toàn bộ, việc đấu vật với lợn sẽ dễ dàng hơn), ~có thể sẽ thuận tiện hơn.


Ở những nơi khác, ví dụ như trong Python, ~$HOMEphải được mở rộng bởi các chức năng khác nhau . Một số nơi khác cho phép các biến và không cho phép cú pháp shell khác như ký tự đại diện hoặc mở rộng dấu ngã (ví dụ: ~/.pam_environmentcó cú pháp đặc biệt để mở rộng biến). Tuy nhiên, những nơi khác cho phép mở rộng dấu ngã như một ngoại lệ (ví dụ: systemd ), nhưng truy vấn trực tiếp cơ sở dữ liệu mật khẩu thay vì sử dụng $HOME.


Một sự khác biệt lớn khác, mà bạn hiển thị ở đây, nhưng không đề cập, là bạn có thể thay đổi giá trị của $HOME, nhưng bạn không thể (trực tiếp) thay đổi giá trị của ~.
Joe

Vì vậy, tôi đã hỏi khi làm $HOME~không đề cập đến cùng một điều - họ thường làm theo mặc định - và sau đó bạn cố tình gán cho biến môi trường để làm cho chúng không đề cập đến cùng một điều. Đây là một minh chứng tốt nhưng không cần thiết phải bối rối.
H2ONaCl

1

$ HOME / có nhiều khả năng hoạt động trong POSIX.2 Bourne / bin / sh tiêu chuẩn vì mở rộng dấu ngã là một phần mở rộng được tìm thấy trong BSD csh tcsh GNU bash và các phần mềm khác.

Nếu bạn muốn viết các tập lệnh di động vào busybox hoặc dash hoặc BSD sh, hãy đầu tư vào các chữ cái thêm kẻo bạn gặp sự cố với ~ /: Không có tệp hoặc thư mục như vậy trên các hệ thống nhất định.

Tôi cũng tìm thấy $ HOME / dễ đọc hơn.


Trong một kịch bản dễ đọc và khả năng hiển thị là quan trọng. Có lẽ đây là lý do tại sao các tập lệnh của tôi sử dụng $HOMEvà hiếm khi sử dụng ~. Bản thân trước đây của tôi có lẽ đã biết điều này.
H2ONaCl
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.