কীভাবে প্রতিধ্বনিত হবে!


59

আমি echoএডিটর দিয়ে খোলার পরিবর্তে ফাইলগুলিতে বিষয়বস্তুগুলিকে আইং করে স্ক্রিপ্ট তৈরি করার চেষ্টা করেছি

echo -e "#!/bin/bash \n /usr/bin/command args"  > .scripts/command

আউটপুট :

বাশ:! / বিন / বাশ: ইভেন্ট পাওয়া যায় নি

আমি এই অদ্ভুত আচরণের বিচ্ছিন্ন থাকেন ঠুং

$ echo !
!  

$ echo "!"
bash: !: event not found

$ echo \#!
#!

$ echo \#!/bin/bash
bash: !/bin/bash: event not found
  • ব্যাং কেন এটি ঘটাচ্ছে?
  • এই "ইভেন্টগুলি" কী বলে বাশ বোঝায়?
  • আমি কীভাবে এই সমস্যাটি পার করব এবং স্ক্রিনে বা আমার ফাইলে "#! / Bin / bash" মুদ্রণ করব?

উত্তর:


59

একক উদ্ধৃতি ব্যবহার করার চেষ্টা করুন।

echo -e '#!/bin/bash \n /usr/bin/command args'  > .scripts/command

echo '#!'

echo '#!/bin/bash'

সমস্যাটি দেখা দিচ্ছে কারণ বাশ! / বিন / ব্যাশের জন্য এর ইতিহাস অনুসন্ধান করছে। একক উদ্ধৃতি ব্যবহার করা এই আচরণ থেকে রক্ষা পায়।


3
এটি স্ট্রিং ইন্টারপোলেশনও অক্ষম করে :(
হুব্রো

এটাই আসল কথা! আপনি একই ইকো কমান্ডে ডাবল কোট ব্যবহার করে অন্যান্য যুক্তি যুক্ত করতে পারেন এবং সেই অংশগুলিতে ইন্টারপোলেশন পেতে পারেন।
রিচম

3
আপনি এর সাথে ব্যাশে সি স্টাইলের স্ট্রিং ব্যবহার করতে পারেন $''। উদাহরণস্বরূপ, echo $'1!\n2!\n3!\n'প্রতিটি সংখ্যা প্রিন্ট করে তারপরে একটি ঠুং শব্দ এবং একটি নতুন লাইন।
spelufo

1
মাল্টি-লাইনের স্ট্রিংয়ের প্রবেশের সময় একক উদ্ধৃতিগুলিতে ব্যাং লাগানো আমাকে সাহায্য করেনি:! বাশ — একক উদ্ধৃতি
ঠাঁই থেকে বাঁচবে

1
@ কেবোলিনো আপনি ঠিক বলেছেন সুতরাং পুরো উদাহরণটির স্ট্রিংটি echo '0123'"$var"'456'হ'ল:, একক উদ্ধৃতিগুলির দুটি জোড়া এবং এক জোড়া ডাবল উদ্ধৃতি নোট করুন।
ফায়াত

16

রিচম যেমন বলেছিলেন , বাশ একটি ইতিহাসের ম্যাচ করার চেষ্টা করছে । এটি এড়ানোর আরেকটি উপায় হ'ল \:

$ echo \#\!/bin/bash
#!/bin/bash

যদিও সাবধান থাকুন যে ডাবল উদ্ধৃতিগুলির মধ্যে রয়েছে, সেগুলি \সরানো হয়নি:

$ echo "\!"
\!

8
ব্যাশে, "\!"আসলে পসিক্স সম্মতিতে \!নয় !, প্রসারিত হয় ।
মাইকেল

@ মাইকেল দীর্ঘশ্বাস
Zsh

মাল্টলাইন স্ট্রিং প্রবেশ করার পরেও এটি কাজ করে। 1 টি মনে রাখবেন যে ব্যাং প্রবেশ করার সময় একটি স্ট্রিংয়ের বাইরে থাকুন এবং এই পদ্ধতিটি (ব্যাকস্ল্যাশ) বেশিরভাগ পরিস্থিতিতে কমপক্ষে অবাক করে কাজ করবে বলে মনে হচ্ছে।
বিনকি

1
স্ক্রিপ্টটি সম্পাদন করার সময় বাশ ইতিহাস অনুসন্ধান করে না তা লক্ষ করা দরকারী হবে, সুতরাং সেখানে এটির জন্য বিশেষ কিছু করার দরকার নেই।
বিনকি

!কোনও যাদু আচরণ না করে কেবল ডাবল কোটের ভিতরে পালানোর কোনও সিনট্যাক্স নেই? এটি বাদাম ...
লাসি

13

!একটি ইতিহাস প্রতিস্থাপন শুরু হয় (একটি "ইভেন্ট" কমান্ড ইতিহাসের একটি লাইন); উদাহরণস্বরূপ !lsধারণকারী গত কমান্ড লাইন থেকে বিস্তৃতি ls, এবং !?fooধারণকারী গত কমান্ড লাইন থেকে বিস্তৃতি foo। আপনি নির্দিষ্ট শব্দগুলিও বের করতে পারেন (যেমন !!:1পূর্ববর্তী কমান্ডের প্রথম শব্দটি বোঝায়) এবং আরও অনেক কিছু; বিশদ জন্য ম্যানুয়াল দেখুন।

এই বৈশিষ্ট্যটি পূর্ববর্তী কমান্ডগুলিকে দ্রুত স্মরণ করার জন্য আবিষ্কার করা হয়েছিল যখন কমান্ড লাইন সংস্করণটি আদিম ছিল। আধুনিক শেলস (কমপক্ষে ব্যাশ এবং জেডএস) এবং অনুলিপি-পেস্টের সাহায্যে ইতিহাসের বিস্তারটি আগের মতো কার্যকর নয় - এটি এখনও সহায়ক, তবে আপনি এগুলি ছাড়া এটি পেতে পারেন।

কোন চরিত্রটি পরিবর্তনশীল সেট করে ইতিহাসের প্রতিস্থাপনকে histcharsপরিবর্তন করতে পারে; যদি আপনি খুব কমই ইতিহাসের বিকল্প ব্যবহার করেন তবে আপনি উদাহরণ স্থাপন করতে পারেন histchars='¡^'যাতে ¡পরিবর্তে ইতিহাসের প্রসার ঘটায় !। এমনকি আপনি পুরোপুরি বৈশিষ্ট্যটি বন্ধ করতে পারেন set +o histexpand


3

নির্দিষ্ট কমান্ড লাইনে ইতিহাসের সম্প্রসারণ অক্ষম করতে সক্ষম হতে আপনি spaceএর তৃতীয় চরিত্র হিসাবে ব্যবহার করতে পারেন $histchars:

histchars='!^ '

তারপরে, আপনি যদি কোনও শীর্ষস্থান দিয়ে আপনার কমান্ডটি প্রবেশ করেন তবে ইতিহাসের সম্প্রসারণ করা হবে না।

bash-4.3$ echo "#!/bin/bash"
bash: !/bin/bash: event not found
bash-4.3$  echo "#!/bin/bash"
#!/bin/bash

উল্লেখ্য তবে নেতৃস্থানীয় স্পেস এছাড়াও ব্যবহার করা হয় যে, যখন $HISTCONTROLধারণ করে ignorespaceএকটি উপায় বলতে যেমন bashইতিহাসে একটি কমান্ড লাইন রেকর্ড করতে না।

আপনি উভয় বৈশিষ্ট্য অনির্দিষ্টভাবে চান, আপনি এর তৃতীয় চরিত্র হিসাবে অন্য একটি চরিত্র চয়ন করতে হবে $histchars। আপনি এমন একটি চান যা আপনার আদেশটি ব্যাখ্যা করার পদ্ধতিকে প্রভাবিত করে না। কয়েকটি বিকল্প:

  • ব্যাকস্ল্যাশ ( \) ব্যবহার করে : \echo fooকাজ করে তবে এটির উপকরণ বা কীওয়ার্ড অক্ষম করার পার্শ্ব প্রতিক্রিয়া রয়েছে।
  • ট্যাব: এটি প্রথম অবস্থানে সন্নিবেশ করতে, আপনাকে Ctrl+VTabযদিও টিপতে হবে ।
  • যদি আপনি দুটো কী টাইপ কিছু মনে না করেন, আপনি যে কোনো চরিত্র সাধারণত প্রথম অবস্থান মধ্যে প্রদর্শিত না (বাছাই করতে পারেন %, @, ?, বাছাই আপনার নিজের) এবং এটির জন্য একটি খালি ওরফে করুন:

    histchars='!^%'
    alias %=
    

    তারপরে সেই অক্ষর, স্থান এবং আপনার আদেশটি প্রবেশ করান:

    bash-4.3$ % echo !!
    !!
    

(আপনি সক্ষম কমান্ড যেখানে ইতিহাস প্রতিকল্পন যদিও অক্ষম করা হয়েছে রেকর্ড করতে না হবে না। এছাড়াও মনে রাখবেন ডিফল্ট 3rd চরিত্র $histcharsহল #যাতে ইতিহাস সম্প্রসারণ মন্তব্য মধ্যে সম্পন্ন করা হয় না। আপনি তা পরিবর্তন পারেন, এবং আপনি এ মন্তব্য লিখুন প্রম্পট, আপনার সত্যটি সম্পর্কে সচেতন হওয়া উচিত! ক্রমগুলি সেখানে প্রসারিত হতে পারে)।


2

প্রস্তাবিত সমাধানগুলি কাজ করে না, উদাহরণস্বরূপ, নিম্নলিখিত উদাহরণ:

$ bash -c "echo 'hello World!'"
-bash: !'": event not found
$

এক্ষেত্রে ঠাঁইটি তার অক্টাল এএসসিআইআই কোড ব্যবহার করে মুদ্রণ করা যেতে পারে:

$ bash -c "echo -e 'hello World\0041'"
hello World!
$

1
আপনার প্রথম কমান্ডে, !দ্বিগুণ উদ্ধৃতিগুলির মধ্যে রয়েছে, যেখানে অন্যান্য উত্তরগুলি সূচিত করে এটির ইতিহাস প্রসারিত অর্থ ধরে রাখা হয়েছে। আপনি ব্যবহার করতে পারেন bash -c 'echo '\''hello World!'\'বা bash -c "echo 'hello World"\!"'"
গিলস

-I প্যারামিটার ব্যতীত, পরিবেশটি পরিবর্তিত হতে পারে (আপনার pr /। প্রোফাইলটি চালিত হয় না)। তবে, -i করার অর্থ আপনার। প্রোফাইল থেকে যে কোনও আউটপুট আসলে আপনি যে কমান্ডটি চালাতে চান তার আউটপুটে বন্দী হবে।
ব্রেন্ট 21 এ 18

-1

4.3 বাশ থেকে, আপনি এখন ইতিহাসের সম্প্রসারণের চরিত্রটি উদ্ধৃত করতে ডাবল উদ্ধৃতি ব্যবহার করতে পারেন:

$ bash --version
GNU bash, version 4.3...
[...]
$ echo "Hello World!"
Hello World!

4
না, এটি কেবল !পরে অনুসরণ করা "আর বিশেষ নয়। echo "foo!"ঠিক আছে, echo "foo!bar"তা নয়
স্টাফেন চ্যাজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.