Tôi tự hỏi, nếu một mình cd gửi tôi đến thư mục nhà của tôi và cd ~ cũng vậy, tại sao ~ lại được thêm vào ngay từ đầu?
Đây có phải là một cái gì đó cụ thể cho BASH hoặc họ sẽ cư xử khác trong Shell khác?
Tôi tự hỏi, nếu một mình cd gửi tôi đến thư mục nhà của tôi và cd ~ cũng vậy, tại sao ~ lại được thêm vào ngay từ đầu?
Đây có phải là một cái gì đó cụ thể cho BASH hoặc họ sẽ cư xử khác trong Shell khác?
Câu trả lời:
Có ~
thể được sử dụng cho nhiều hơn thế. Bất kỳ lệnh nào cũng có thể thu lợi từ việc có một phím tắt đến thư mục chính. Vì vậy, không cần thiết nếu bạn muốn cd vào nhà của bạn, nhưng những gì về ~/.config
?
$ cd ~/.config
Nếu không, bạn phải viết ra đường dẫn về nhà, sử dụng $HOME
var hoặc thực hiện hai cd
s. Ngoài ra để sao chép hoặc di chuyển tập tin:
$ cp ~/downloads/some-file some/path/
Vì hầu hết các tệp của bạn đều ở trong nhà nên luôn có một phím tắt.
~
là làm cd ~user/download
để đi đến thư mục tải xuống của người dùng.
Việc cd
cơ bản là gọi cd
mà không có đối số và theo cd
hành vi "... nếu dir không được cung cấp, giá trị của biến shell HOME là mặc định." (từ hướng dẫn sử dụng bash ). Ngược lại, cd ~
là khi bạn cung cấp đối số cho cd
lệnh, điều này xảy ra ~
và shell sẽ thực hiện mở rộng dấu ngã . Theo như quay trở lại thư mục nhà của người dùng - không có sự khác biệt. Trong cả hai trường hợp, HOME
biến môi trường sẽ được truy vấn:
$ env 'HOME=/usr' bash -c 'cd;pwd; cd ~;pwd'
/usr
/usr
Hiệu quả, điều này cũng không có sự khác biệt từ cd $HOME
. Tuy nhiên, trong khi cd
sẽ làm một và chỉ một điều, dấu ngã có thể được sử dụng để thực hiện các mở rộng khác, chẳng hạn như ~+
cho thư mục làm việc hiện tại.
Tuy nhiên, đủ thú vị là chúng ta có thể unset HOME
phá vỡ cd
nhưng ~
vẫn sẽ hoạt động:
$ bash -c 'cd /usr;unset HOME;cd;pwd;cd ~;pwd'
bash: line 0: cd: HOME not set
/usr
/home/xieerqi
Tại sao ? Một lần nữa, trả lời trong hướng dẫn:
Nếu HOME không được đặt, thư mục chính của người dùng thực thi shell được thay thế. Mặt khác, tiền tố dấu ngã được thay thế bằng thư mục chính được liên kết với tên đăng nhập được chỉ định.
Lưu ý rằng việc không cài đặt là khác nhau khi tạo biến rỗng HOME=
và có hiệu lực. Tài liệu nói cụ thể về biến unset. Biến biến bằng chuỗi rỗng có tác dụng ngược lại với những gì chúng ta mong đợi:
bash-4.3$ env 'HOME=' bash -c 'cd /usr;set|grep "^HOME"; stat -c "%F" ~;cd;pwd'
HOME=
stat: cannot stat '': No such file or directory
/usr
Ở đây bạn có thể thấy rằng làm cho HOME
chuỗi rỗng phá vỡ cả dấu ngã và cd
hành vi.
Tilde và $HOME
có một số khác biệt và lý do khác nhau để tồn tại. $HOME
là một biến shell, cũng là một biến ngẫu nhiên là một trong các biến môi trường - và nó có sẵn cho tất cả các chương trình; trong C bạn sẽ sử dụng environ()
để truy cập đó. Ngược lại, tilde
cú pháp dành riêng cho shell thực hiện mở rộng dấu ngã, mặc dù bạn cũng có thể sử dụng wordexp()
chức năng để thực hiện mở rộng giống như shell ( tham chiếu ) trong C.
Lý do tại sao ~
đại diện HOME
đã được trả lời trong câu hỏi này : đã có lúc nhân vật dấu ngã chia sẻ cùng khóa với HOME
trên thiết bị đầu cuối Lear-Siegler ADM-3A. HOME
ngược lại là biến môi trường có ý nghĩa biểu tượng thuần túy và không có biểu diễn vật lý.
Ngoài ra, thực tế HOME
là một biến môi trường cho phép chúng ta bỏ đặt nó, trong đó chúng ta không thể đặt ~
thành một thứ khác thông qua các phương tiện đơn giản.
# cd ~ will still work, because ~ is blank, so it's same as just cd
$ bash -c 'unset HOME; echo $HOME; cd ~;pwd'
/home/xieerqi
$ env 'HOME=' bash -c 'echo $HOME; cd ~;pwd'
/home/xieerqi
Lưu ý dòng trống nơi đầu tiên echo
xuất ra biến unset và thực tế là như vậy. Ngược lại, chúng ta không thể làm những thứ như thế này để đánh dấu:
$ bash -c '~=; cd ~;pwd'
bash: ~=: command not found
/home/xieerqi
$ bash -c '~=$'\0'; cd ~;pwd'
bash: ~=bash: command not found
/home/xieerqi
$ bash -c 'unset ~; cd ~;pwd'
bash: line 0: unset: `/home/xieerqi': not a valid identifier
/home/xieerqi
Tuy nhiên, thay đổi HOME
không ảnh hưởng đến ~
:
$ env 'HOME=' bash -c 'echo $HOME; stat ~;'
stat: cannot stat '': No such file or directory
Ngoài ra, vì ~
cũng hoạt động như nhân vật mở rộng, chúng ta có thể làm những thứ như thế này để hiển thị thư mục làm việc hiện tại:
$ bash -c 'cd /etc/;stat -c "%n" ~+'
/etc
Trong khi đó, nếu chúng ta muốn làm điều đó thông qua các biến môi trường, chúng ta cần PWD
và HOME
giữ nguyên, hoặc nếu bạn làm những việc như thế echo $HOME+
- đó chỉ là kết hợp chuỗi / biến. Nhưng một lần nữa, ~+
đưa thông tin ra khỏi các biến môi trường:
$ bash -c 'cd /etc/;PWD="/usr";stat -c "%n" ~+'
/usr
LƯU Ý : ~+
và ~-
mở rộng hoạt động trong ksh
, nhưng không trong dash
.
Để trả lời một số câu hỏi cụ thể của bạn:
Đây có phải là một cái gì đó cụ thể cho BASH hoặc họ sẽ cư xử khác trong Shell khác?
Không, đây phải là hành vi nhất quán. ksh
, dash
và csh
- tất cả đều cư xử giống với cd
hoặc cd ~
.
Tại sao ~ được thêm vào ở vị trí đầu tiên sau đó?
Tôi sẽ nói sự thuận tiện và lý do lịch sử như được giải thích trong câu trả lời liên kết về dấu ngã. Cuối cùng, nó đã phát triển để thực hiện nhiều hơn là chỉ mở rộng thư mục nhà.
Bất kể bạn ở một số cấp độ thư mục trên hay dưới $HOME
, các lệnh cd
và cd ~
thực hiện cùng một thứ và không khác nhau - nó sẽ đưa bạn trở lại thư mục HOME của bạn.
TUY NHIÊN: Khi bạn có 1 hoặc nhiều cấp thư mục trên HOME và bạn muốn TRỰC TIẾP đến thư mục con 1 hoặc nhiều cấp thư mục bên dưới $HOME
, dấu ngã ( ~
) có ích bằng cách lưu bạn gõ phím khi được sử dụng để thay thế văn bản cần tham khảo để $HOME
khi gõ một cd
lệnh. Ví dụ;
/$ cd # (or cd ~)
~$ pwd
/home/foo
~$ dir
bar bar2 bar3
~$ cd ..
/$ cd ..
/$ pwd
/
/$ cd /bar3
bash: cd: /bar3: no such file or directory
/$ cd ~/bar3 # (instead of "cd /home/foo/bar3")
~/bar3$ pwd
/home/foo/bar3
~ là viết tắt của / home / tên người dùng, vì vậy bạn tiết kiệm thời gian khi gõ. Ví dụ: cd / home / tên người dùng / Tải xuống giống như cd ~ / Tải xuống, nhưng ít gõ hơn. Cả hai lệnh đều làm như vậy, thay đổi thư mục làm việc sang vị trí đó.
root
thường ở bên ngoài/home
cd ~
vscd $HOME
vscd ~not-tandu
. Câu hỏi này được hỏi vềcd
vscd ~
.