שאלה מה זה "-Bash:!": האירוע לא נמצא "


נסה לבצע את הפעולות הבאות תחת פגז bash echo "Reboot your instance!"

על ההתקנה שלי:

root@domU-12-31-39-04-11-83:/usr/local/bin# bash --version
GNU bash, version 4.1.5(1)-release (i686-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@domU-12-31-39-04-11-83:/usr/local/bin# uname -a
Linux domU-12-31-39-04-11-83 2.6.35-22-virtual #35-Ubuntu SMP Sat Oct 16 23:57:40 UTC 2010 i686 GNU/Linux
root@domU-12-31-39-04-11-83:/usr/local/bin# echo "Reboot your instance!"
-bash: !": event not found

מישהו יכול בבקשה להסביר מה הוא "אירוע bash?" מעולם לא שמעתי את המושג הזה לפני כן. כמו כן, איך אני צריך פלט "!" בסוף המשפט?


90
2017-12-02 10:45






תשובות:


אתה יכול לכבות את תחליף ההיסטוריה באמצעות set +H.


41
2017-12-02 16:31



האם אתה יודע את ההיגיון מאחורי התחביר? זה נראה ממש נגד אינטואיטיבי. היית חושב שתקליד +H כדי לאפשר משהו -H כדי להשבית משהו. - PunkyGuy
@ PunkyGuy: אני לא יודע את ההיסטוריה (משחק מלים המיועד) מאחורי זה, אבל אפשרויות יוניקס בדרך כלל להתחיל עם מקף (או מינוס) ו + הוא פשוט ההפך מזה. - Dennis Williamson


! הוא אופי מיוחד כדי bash, הוא משמש כדי להתייחס פקודות קודמות; למשל,

!rm

ייזכר ויבצע את הפקודה האחרונה שהחלה במחרוזת "rm", ו

!rm:p

ייזכר אך לא יבצע את הפקודה האחרונה שהחלה במחרוזת "rm". באש הוא לפרש את סימן הקריאה ב echo "reboot your instance!" כפי ש "תחליף כאן את הפקודה האחרונה שהחלה עם הדמויות מיד לאחר סימן הקריאה", והוא רוטן לך כי זה לא יכול למצוא אירוע (הפקודה) בהיסטוריה שלך, כי התחיל עם ציטוט כפול יחיד.

נסה

echo reboot your instance\!

כדי להגן (לברוח) את סימן הקריאה מ bash.


86
2017-12-02 10:49



כן, אבל צריך לקרות אם אני רוצה להשתמש הד -e "קצת טקסט $ ENV_VAL עוד טקסט \ nRootoot עכשיו!" ? - Maxim Veksler
לכתוב שתי הצהרות הד; אתה מקבל את linefeed בחינם. - MadHatter
פתרון פשוט הוא להשתמש ציטוטים בודדים ציטוטים כפולים בבת אחת: הד- e "טקסט \ nReeboot" '! - mmey
זה מסריח. אם לא אצליח להימלט מסימן הקריאה, באש זורק התקף. אם אני לעשות להימלט ממנה, הקו נטוי הפוך נכלל במחרוזת הסופית. למה אתה עושה את זה, Bash !! (pastebin.com/g4PYv56A) - Hubro
@Hubro בהגינות, אני לא בטוח שזה הכל באש של אש. יש לך עניינים מסובכים במקצת על ידי שימוש באודם כדי להאכיל דברים, וזה לא ברור לי איזה חלק אודם משחק בהפשטת או חיזוק של תווים לברוח. - MadHatter


כדי לפתור את הבעיה המקורית שלך, נסה להשתמש במרכאות בודדות במקום במרכאות כפולות. עם זאת, bash ינסה להרחיב תווים מסוימים לפני העברת התוצאה אל הפקודה (הד במקרה זה). עם ציטוטים בודדים, באש מעביר את כל המחרוזת, ללא שינוי.

! משמש בפקודות כדי להתייחס להיסטוריית שורת הפקודה. ראה: http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS עבור סט מלא. עם הדוגמה לעיל, באש מנסה להרחיב !" כהתייחסות לאירוע לפני הד מקבל מבט פנימה, ומכאן השגיאה.

שים לב שבסקריפטים, את כל של פקודות ההיסטוריה אינן זמינות, שכן הן הגיוניות רק בקונכייה אינטראקטיבית.

רק אחד אני משתמש על בסיס קבוע, הוא !$. הוא מתרחב לארגומנט האחרון של הפקודה הקודמת. זה קצרנות שימושי במקומות.


22
2017-12-02 11:02



!! למלא את הפקודה האחרונה שהוזנה היא שימושית להפליא; במיוחד, sudo !! או pfexec !! - jgoldschrafe
אני גם מוצא sudo ו pfexec להיות כלי עזר נחמד, אבל לא צריך להיות כל כך נלהב. - LeartS
$_ עובד יותר פגזים מאשר באש וזה משתנה ראוי, בניגוד !$. (ו @ LeartS: אהבתי את הבדיחה של חוסר סמלי הבדיחה.)) - ΤΖΩΤΖΙΟΥ


פשוט לשים רווח בין! ו"זה יעבוד.

לחיים.


5
2017-09-25 07:06



האם אתה יכול להוסיף הסבר מדוע הפתרון שלך עובד? - 200_success
זה עובד בגלל בש רק מתייחס! כמו אופי מיוחד אם זה ישירות ואחריו אופי שאינו רווח לבן. עם זאת, זה יהיה גם להוסיף ריק נוסף הפלט שלך, כך שאולי לא תמיד יהיה הרצוי ... - mmey


כן, ! הוא תו מיוחד כדי bash, הוא משמש כדי להתייחס פקודות קודמות.

כמה דרכים אתה יכול להתמודד עם המצב

הבא יהיה פלט את המחרוזת כפי שהיא

echo 'Reboot your instance!'

הבא יבצע את הפקודה ואת שרשראות מחרוזת

echo 'escaping #'" adding `which python` to the string"
echo '#!'`which python`

2
2018-04-25 13:57





ב bash 4.3 נראה שאתה כבר לא צריך להשתמש ציטוטים בודדים או set +HYou

$ bash --version
GNU bash, version 4.3.46(1)-release (x86_64-unknown-linux-gnu)
[...]
$ echo "Reboot your instance!"
Reboot your instance!

1
2017-07-12 14:43



כנראה באג, כי כאן, יש לי 4.4.12, שוב, אני צריך set +H או ציטוט. או שיש לך set +H איפשהו (כמו ב /etc/profile). - Bodo Thiesen
שימוש! - לא בסוף המשפט מאמת את אירוע האירוע של באש עדיין עובד בסדר. גרסה 4.3.30 ........ $ הד "בדוק שוב את המשפט שלך!" Fash "bash:! Foo: האירוע לא נמצא - JohnnyD92


אתה יכול גם להשתמש heredocYou

cat <<EOF
Reboot your instance!
EOF

זה מעצבן במקרה זה כי זה לא אחד אניה אבל עבור פקודות ארוכות יותר (כמו כתיבת סקריפט bash), זה עובד נהדר.


0
2017-07-07 11:41