Як використання тильди працює як ярлик до мого домашнього каталогу?


30

Я розгубився, намагаючись скопіювати деякі файли з одного ПК на інший. Я це зрозумів, але синтаксис все ще мене бентежить. Це працює:

scp ~/Desktop/Volenteer.png jay@server.ip:~j0h/b

який кладе Volenteer.pngв папку /home/j0h/b. Однак це не працює:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Це також не вдається, надавши файл статусу виходу 1 файл не знайдено:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

Як це робиться:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Так очевидно, що є якась різниця між, ~і ~/ ця різниця полягає в наявності/

$~/
bash: /home/j0h/: Is a directory
$ ~
bash: /home/j0h: Is a directory

Так чому в scp, ~вирішує ~/? Це здогадка, я не можу перевірити, що це відбувається. Але це здається непослідовним, а тому заплутаним. Це помилка в scp? або щось про тильду я пропускаю?


2
Лише бічна примітка тут написана "добровольцем", а "U" замість "e" :)
AER

2
Я ліберальний спеллер.
j0h

Питання, пов'язані з цим: askubuntu.com/q/972319/295286
Сергій Колодяжний

Відповіді:


68

~ - ваш домашній каталог.

~foo- це домашній каталог користувача foo, якщо такий користувач існує, або просто каталог з ім'ям ~foo, якщо цього користувача не існує.


Отже, в:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

~Desktopрозшириться до домашнього каталогу користувача Desktop, якщо такий користувач існує (а зазвичай його немає), або буде просто ~Desktop(шлях, який зазвичай також не існує).


В:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

~/j0hрозшириться до каталогу з ім'ям j0hу jayдомашньому каталозі, який, знову ж таки, навряд чи існує.


Це не ~та ~/де різниця має місце, але в ~і ~foo.


Крім того, ~також може використовуватися для навігації по історії каталогів:

  • ~-- це попередній робочий каталог (як $OLDPWD)
  • ~+- це поточний робочий каталог (як $PWD)

Це не стосується scp, оскільки ви не можете змінювати каталоги в середині scpоперації.

І якщо ви використовуєте pushdтаpopd підтримуєте стек каталогів, і це буде той каталог у стеці каталогів, як видно на виході . буде найменшим каталогом з кінця (рахуючи від нуля, в обох випадках). Наприклад:~N~+NNdirs~-NN

$ for i in etc usr var tmp; do pushd /$i; done
/etc ~/.vim
/usr /etc ~/.vim
/var /usr /etc ~/.vim
/tmp /var /usr /etc ~/.vim

$ dirs
/tmp /var /usr /etc ~/.vim

Потім можна отримати доступ до каталогів у стеці, використовуючи:

/tmp /var /usr /etc ~/.vim
  ~0   ~1   ~2   ~3     ~4
 ~+0  ~+1  ~+2  ~+3    ~+4
 ~-4  ~-3  ~-2  ~-1    ~-0 
  ~+   ~-

Отже, ~+це завжди рівнозначно .тоді, чи не так? Здається зайвим.
Уайлдкард

1
@Wildcard добре, не точно. ~+і ~-використовувати значення $PWDі $OLDPWD, які є абсолютними шляхами. .завжди відносний шлях. Отже, якщо є команда, яка змінює поточну робочу директорію при виконанні, вона побачить новий шлях для ., де шлях, розширений на ~-, залишиться тим самим. tar -Cце приклад, хоча, я визнаю, я не можу придумати корисного для цього ~+. $PWDбуло б так само добре, за винятком того, що вам не потрібно цитувати, ~+/foo/barякщо вони $PWDмістять пробіли.
муру

1
Дякую, що це пояснює. Насправді це хороший приклад використання випадку прямо тут: деякі команди відмовляються працювати на відносних шляхах з міркувань безпеки; з такими командами ви не можете користуватися, ./filenameале можете використовувати "$PWD/filename"або простіше ~+/filename. (І деякі команди будуть працювати над відносними іменами шляхів, але є функціональна різниця, наприклад, lnабо tar.)
Wildcard

21

Прочитайте документацію GNU для розширення Bash Tilde (як я мав би бути перед першою ітерацією цієї відповіді).

~/Desktopі ~j0hробите принципово різні речі, що пояснює, чому ~Desktopне працює:

  • Звичайна зміна ~поточної $HOMEсередовища, встановленої при вході в систему, є простою . Так ~вирішує /home/oliдля мене і ~/Desktopчитає як /home/oli/Desktop. Тут ви бачите, що тильда використовується найбільше.

  • ~usernameвирішує адресу будинку цього користувача , як зазначено в /etc/passwd. Тому ~oliвирішується /home/oli, що ~j0hможе вирішити, /home/j0hале не обов'язково, ваш хомедір може бути де завгодно.

  • ~not-a-usernameне вирішує. Оскільки Desktopне є користувачем, ~Desktopне замінюється. Це сприймається буквально як назва файлу або шляху ~Desktop(якого тут немає).

І зайве говорити, що все це відбувається віддалено (було б марно, scpякби його замінили на місцеві значення). Це працює, тому що Bash не замінить, ~...якщо йому передує щось, окрім пробілу.


Що getent passwd binговорить?
муру

2
"bin" - це системний користувач на більшості машин Linux, з домашнім каталогом / bin.
fNek

1
Неможливість розширення ~dirузгоджується з документами GNU: "... символи в префіксі tilde після тильди трактуються як можливе ім'я для входу ... Якщо ім'я для входу недійсне, або розширення tilde не вдається, слово залишається без змін ". Тут dirне є ім’я користувача в цій системі, тому воно залишається незмінним.
апспіллери

Дякую всім. Я, мабуть, повинен прочитати посилання, які я публікую :)
Олі

4

Символ ~використовується як ярлик для /home/userв bash, тому у випадку ~/Desktop/Volenteer.pngйого є скороченим для /home/user/Desktop/Volenteer.png.

Тож, як ви бачите /, показаний, як завжди, новий рівень в ієрархії файлової системи.


3
лише наполовину праворуч, це скорочення для змінної середовища $ HOME. ~{user}/може бути просто будь-який випадковий шлях, встановлений файлом бази даних passwd (5). Хоча так, стандарти filesytem.org розміщують постійних користувачів у / home, це не так, як у кожного користувача (наприклад, root в / root та служби в / var / ... або старих Unixies, які використовують / usr замість / home)
Дуайт Спенсер

DwightSpencer правильний. Я підтримую декілька серверів, де користувачі перебувають у / usr / {CLIENTNAME} / home / і мають спільний доступ до декількох внутрішніх та віддалених систем (усі вказують на цей каталог), тому потрібно підтримувати лише 1 систему. І ~ вказує на цей каталог;)
Rinzwind

3
@Rinzwind eek. Я маю висловити протест проти цієї безславної злочинності /usr.
муру

@muru hey це був не МОЙ дзвінок>: - D Це було залишено від ШОС D:
Rinzwind

1
Чесно кажучи, мені сподобалося використання / usr для всіх речей користувачів, оскільки саме так воно і означало спочатку. Що я вважаю сьогодні, це більш негідне зловживання / usr / bin як великого уніфікованого сміттєзвалища всіх бінарних файлів (sys, користувач, sysop) поза базовими бінутами. Зрештою / usr малося на увазі, оскільки всі речі користувачі мають доступ до витягнутої з монтажу nfs, тоді як / usr / local - це місцевий простір користувачів з / sbin як бінарні системи sysop та / bin system binaries. Я розумію, що / home може бути іншим розділом, але так можна / usr / home / ... зберігаючи його в / usr, зберігає його як простір імен користувачів як у політиці, реалізації, так і в мисленні.
Дуайт Спенсер

3

~є скороченням змінної середовища $HOMEна більшості похідних оболонок c / підтримуючих оболонок, сумісних з POSIX. найпоширенішим способом використання ~є посилання на ваш власний домашній каталог або додому іншого користувача:

cd ~ # ie shell, take me to my home folder

cd ~root # i.e. shell, take me to root's home folder

Щоб знайти домашній каталог для будь-якого локального користувача в системі POSIX (UNIX, Linux, OS X, BSD), яка використовує базу даних passwd (5), запустіть awk /etc/passwdтак:

awk -F: '{ print $1,$(NF-1) }' /etc/passwd

Тут буде вказано список кожного локального користувача та їх домашнього каталогу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.