Що означає! $?


32

Я переглядаю підручник і в ньому згадується запустити цю команду:

sudo chmod 700 !$

Я не знайомий !$. Що це означає?


5
Зазвичай безпечно спробувати echoщось, якщо ви не впевнені, що це зробить.
Шадур

8
@Shadur, не завжди. echo $(rm -rf /)
cjm

1
@cjm Якщо ви не маєте дійсно стару систему, вам потрібен --no-preserve-rootваріант, і якщо ви побачите в програмі слова "без збереження", краще подумайте ретельно про те, що це робить.
wchargin

4
@WChargin Будьте дуже обережні, вважаючи, що "дійсно старий" і "не Linux / не використовує GNU coreutils" - це одне і те ж; вони ні.
Кріс Даун

Відповіді:


44

В основному, це останній аргумент попередньої команди.

!$є "кінцем" попередньої команди. Розглянемо наступний приклад: почнемо з пошуку слова у файлі:

grep -i joe /some/long/directory/structure/user-lists/list-15

якщо Джо є в цьому списку користувачів, ми хочемо видалити його з нього. Ми можемо запустити vi з тим довгим деревом каталогів як аргумент, або просто так, на vi !$який баш розгортається:

vi /some/long/directory/structure/user-lists/list-15

( джерело ; зручний довідник, до речі)


Нічого не варто відрізняти цей !$маркер і спеціальну змінну оболонки $_. Дійсно, обидва розширюються до останнього аргументу попередньої команди. Однак !$розгортається під час розширення історії , тоді $_як розгортається під час розширення параметрів . Одним з важливих наслідків цього є те, що при використанні !$, то розширена команда зберігається в історії.

Наприклад, розглянемо натискання клавіш

  • echo Foo Enter echo !$ Jar Enter Up Enter; і

  • echo Foo Enter echo $_ Jar Enter Up Enter.

(Змінені лише символи - це $!і $_в середині.)

У першому, коли ви натискаєте Up, командний рядок зчитується echo Foo Jar, тому останній рядок, записаний у stdout, є Foo Jar.

В останньому, коли ви натискаєте Up, командний рядок читає echo $_ bar, але тепер $_має інше значення, ніж це було раніше - справді, $_це зараз Jar, тому останній рядок, записаний у stdout, є Jar Jar.

Іншим наслідком є ​​те, що _можна використовувати в інших розширеннях параметрів, наприклад, послідовності команд

printf '%s '    isomorphism
printf '%s\n'   ${_%morphism}sceles

відбитки isomorphism isosceles. Але немає аналогічного ${!$%morphism}розширення.

Для отримання додаткової інформації про фази розширення в Bash, дивіться EXPANSIONрозділ man 1 bash(це називається розширення Shell в інтернет-видання). HISTORY EXPANSIONРозділ окремо.


6
Приємно. Добре знати. Також добре, що є обмін стеками. Важко шукати в Google щось подібне!$
Ендрю

4
BTW, у командному рядку ви можете вставити останній аргумент попередньої команди insert-last-argument, зазвичай пов'язаний з M-..
choroba

1
@Andrew, будь ласка, не забудьте прийняти це, якщо він відповість на ваше запитання. Прийняття та надсилання пропозицій, а не розміщення коментарів - це те, як висловлюються подяки в мережі SE, дивіться тут "офіційну" позицію.
terdon

1
@Andrew FYI, я шукав у Google "bash bang dollar" і отримав гідні результати, включаючи це посилання як третій список.
wchargin

1
@terdon я спробував прийняти відповідь минулої ночі, але це було так швидко, що я змушений був чекати, щоб прийняти її.
Андрій

4

Строго кажучи, !$це останнє слово останньої команди зі списку історії.

слово - Послідовність символів, оброблених оболонкою як одиниця. Слова можуть не включати в себе котирувані метахарактеристики.

метахарактер - Символ, який, коли не цитується, розділяє слова. Метахарактер - це порожній або один із наступних символів: '|', '&', ';', '(', ')', '<' або '>'

blank - символ пробілу чи вкладки.

Приклади:

set -o history # enable command history
set -o histexpand # enable ! style history substitution

HISTSIZE=10

# save all lines on the history list    
HISTCONTROL=
HISTIGNORE=

date
echo !$ # prints date

date>/dev/null
echo !$ # prints /dev/null

echo a b c>/dev/null
echo !$ # prints /dev/null

HISTCONTROL=ignorespace # lines which begin with a space character are not saved in the history list
echo a b c
 echo d e f # space at the beginning
echo !$ # prints c


-3

!$ дасть вам останню команду, що використовується для конкретного користувача ....

ви також можете знайти історію команд, використаних раніше, скориставшись historyкомандою ... спробуйте ...

ПРИМІТКА. Для конкретного користувача всі використані раніше команди зберігатимуться у файлі історії bash.


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