سؤال ما هو "-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

هل يمكن لأي شخص أن يشرح ما هو "أحداث باش؟" لم اسمع هذا المفهوم من قبل. أيضا ، كيف يمكنني إخراج "!" في نهاية الجملة؟


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

سوف يتذكر ولكن لا تنفيذ الأمر الأخير الذي بدأ مع السلسلة "جمهورية مقدونيا". باش يفسر علامة التعجب في echo "reboot your instance!" مثل "استبدل هنا الأمر الأخير الذي بدأ بالحرف (الأحرف) مباشرةً بعد علامة التعجب"، ويتذمر من أنه لا يمكنه العثور على حدث (أمر) في السجل الخاص بك والذي بدأ بعلامة اقتباس مزدوجة واحدة.

محاولة

echo reboot your instance\!

لحماية (الهروب) علامة التعجب من bash.


86
2017-12-02 10:49



نعم ، ولكن يجب أن يحدث إذا أردت استخدام echo -e "some text $ ENV_VAL some more text \ nReboot now!" ؟ - Maxim Veksler
اكتب اثنين من عبارات الصدى. يمكنك الحصول على تغذيه مجانيه. - MadHatter
الحل البسيط هو استخدام علامات الاقتباس الفردية والاقتباسات المزدوجة في آن واحد: echo -e "Text \ nReeboot" '!' - mmey
هذا يمتص. إذا لم أتمكن من الهروب من علامة التعجب ، فإن bash يلقي نوبة. اذا انا فعل تهرب منه ، يتم تضمين الشرطة المائلة للخلف في السلسلة النهائية. لماذا تفعل هذا ، باش! (pastebin.com/g4PYv56A) - Hubro
Hubro في الإنصاف ، لست متأكدا من أن كل خطأ باش. لديك بعض الأمور المعقدة باستخدام روبي لتغذية الأشياء باش ، وليس من الواضح بالنسبة لي ما هو الدور الذي يلعبه روبي في تجريد أو تعزيز شخصيات الهروب. - MadHatter


لحل مشكلتك الأصلية ، حاول استخدام علامات الاقتباس الفردية بدلاً من علامات الاقتباس المزدوجة. مع هذا الأخير ، سيحاول bash توسيع بعض الأحرف قبل تمرير النتيجة إلى الأمر (صدى في هذه الحالة). مع علامات الاقتباس المفردة ، يمرّ bash السلسلة بأكملها دون تغيير.

! يستخدم في الأوامر للإشارة إلى محفوظات سطر الأوامر. نرى: http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS لمجموعة كاملة. مع المثال أعلاه ، تحاول bash التوسع !" كإشارة إلى حدث قبل أن يحصل الصدى على نظرة ، وبالتالي الخطأ.

لاحظ أنه في النصوص ، الكل من أوامر التاريخ معطلة ، لأنها لا معنى لها إلا في قذيفة التفاعلية.

الوحيد الذي استخدمه على أساس منتظم ، هو !$. يتمدد إلى الوسيطة الأخيرة من الأمر السابق. انها اختزال مفيد في الأماكن.


22
2017-12-02 11:02



!! لملء الأمر الأخير الكامل المدخل مفيد بشكل ملحوظ ؛ خصوصا، sudo !! أو pfexec !! - jgoldschrafe
كما أنني أجد sudo و pfexec بمثابة مرافق لطيفة ، ولكن لا حاجة لأن نكون متحمسين للغاية. - LeartS
$_ يعمل في قذائف أكثر من bash وهو متغير مناسب ، على عكس !$. (و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 +H:

$ 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
باستخدام! -char ليس في نهاية الجملة يتحقق من اكتشاف حدث bash لا يزال يعمل بشكل جيد. Version 4.3.30 ........ $ echo "إعادة فحص الجملة! foo" bash:! foo: لم يتم العثور على الحدث - JohnnyD92


يمكنك أيضا استخدام heredoc:

cat <<EOF
Reboot your instance!
EOF

إنه أمر مزعج في هذه الحالة لأنه ليس خطًا واحدًا ولكن لأوامر أطول (مثل كتابة برنامج نصي bash) ، يعمل بشكل رائع.


0
2017-07-07 11:41