কিছু বাশ উদাহরণের মধ্যে সঠিক কমান্ড লাইনটি কার্যকর করা দেখতে পাচ্ছি কী করে?


29

আমার একটি দীর্ঘ চলমান bashউদাহরণ রয়েছে (একটি screenসেশনের অভ্যন্তরে) যা একটি লুপের ভিতরে প্রতিটি কমান্ডের একটি জটিল সেট সম্পাদন করে (প্রতিটি লুপ পাইপ, পুনর্নির্দেশকরণ ইত্যাদি করে)।

দীর্ঘ কমান্ড লাইনটি টার্মিনালের অভ্যন্তরে লেখা ছিল - এটি কোনও স্ক্রিপ্টের অভ্যন্তরে নয়। এখন, আমি বাশ প্রক্রিয়া আইডি জানি, এবং আমার রুট অ্যাক্সেস আছে - আমি কীভাবে দেখতে পাব যে এর ভিতরে সঠিক কমান্ড লাইন কার্যকর করা হচ্ছে bash?

উদাহরণ
bash$ echo $$
1234
bash$ while true ; do \
    someThing | somethingElse 2>/foo/bar | \
    yetAnother ; sleep 600 ; done

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

bash$ echo $$
5678
bash$ su -
sh# cd /proc/1234
sh# # Do something here that will display the string  \
   'while true ; do someThing | somethingElse 2>/foo/bar | \
    yetAnother ; sleep 600 ; done'

এটা কি সম্ভব?

সম্পাদনা # 1

আমি পেয়েছি এমন কিছু উত্তরের জন্য পাল্টা উদাহরণ যুক্ত করা।

  1. ব্যবহার সম্পর্কে cmdlineঅধীনে /proc/PIDকাজ না হলে, অন্তত আমার দৃশ্যকল্প নেই। এখানে একটি সাধারণ উদাহরণ:

    $ echo $$
    8909
    
    $ while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done

    অন্য শেলের মধ্যে:

    $ cat /proc/8909/cmdline
    bash
  2. ব্যবহার ps -p PID --noheaders -o cmdঠিক ততই অকেজো:

    $ ps -p 8909 --no-headers -o cmd
    bash
  3. ps -eaf এছাড়াও সহায়ক নয়:

    $ ps -eaf | grep 8909
    ttsiod    8909  8905  0 10:09 pts/0    00:00:00 bash
    ttsiod   30697  8909  0 10:22 pts/0    00:00:00 sleep 30
    ttsiod   31292 13928  0 10:23 pts/12   00:00:00 grep --color=auto 8909

    এটি হ'ল, অরিজিনাল কমান্ড লাইনের কোনও আউটপুট নেই, যা আমি খুঁজছি - অর্থাত্ while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done

উত্তর:


40

আমি জানতাম যে আমি খড়কে আঁকড়ে ধরছি, কিন্তু ইউনিক্স কখনই ব্যর্থ হয় না!

আমি কীভাবে এটি পরিচালনা করেছি তা এখানে:

bash$ gdb --pid 8909
...
Loaded symbols for /lib/i386-linux-gnu/i686/cmov/libnss_files.so.2
0xb76e7424 in __kernel_vsyscall ()

তারপরে (gdb)প্রম্পটে আমি কমান্ডটি চালিত করেছি, call write_history("/tmp/foo")যা এই ইতিহাসটি ফাইলে লিখবে /tmp/foo

(gdb) call write_history("/tmp/foo")
$1 = 0

আমি তখন প্রক্রিয়া থেকে বিচ্ছিন্ন।

(gdb) detach
Detaching from program: /bin/bash, process 8909

এবং ছেড়ে দিন gdb

(gdb) q

এবং যথেষ্ট নিশ্চিত ...

bash$ tail -1 /tmp/foo
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done

ভবিষ্যতের সহজ ব্যবহারের জন্য, আমি প্রক্রিয়াটি স্বয়ংক্রিয় করে একটি বাশ স্ক্রিপ্ট লিখেছিলাম ।


1
+1 খুব সুন্দর sleuthing. এটিকে 2 দিনের মধ্যে বাদে এ হিসাবে চিহ্নিত করতে ভুলবেন না।
slm

@ এসএলএম: ধন্যবাদ! আমি এটি সম্পর্কে একটি ব্লগ পোস্ট লিখব - এটি মজা ছিল, এটি শিকার করে।
ttsiodras

1
সঙ্গে readline সক্রিয় তুমিও এটা করতে পারেন gdb: print (char *)rl_line_buffer। ক্রমানুসারে বর্তমান কমান্ডটি হ'ল print (char *)the_printed_command। আপনি এটি করতে পারেন call history_builtin(), তবে এটি ব্যাশ প্রক্রিয়াটির tty এ আউটপুট আসবে, সুতরাং এটি কম কার্যকর হতে পারে।
মিঃ স্পুর্যাটিক

11
@ এসএলএম: প্রতিরোধ করতে পারেনি - আমি এটি সম্পর্কে এখানে ব্লগ করেছি: users.softlab.ece.ntua.gr/~ttsiod/bashheimer.html
ttsiodras

1
বাশ থ্রেড-নিরাপদ? আপনাকে আশা করতে হবে আপনি কিছু অভ্যন্তরীণ অবস্থা সংশোধন করছেন না যা আপনি যখন জিডিবি থেকে কিছু সম্পাদন করেন তখন বর্তমানে সম্পাদনকারী কোডটি আপসেট করে। বাস্তবে, যখনই আপনি জিডিবি দিয়ে স্থগিত করার ঘটনা ঘটে তখন বাশ প্রায় অবশ্যই তার শিশু প্রক্রিয়াটি শেষ হওয়ার জন্য অপেক্ষা করবে।
অ্যাড্রিয়ান প্রোঙ্ক

5

যেহেতু কমান্ডটি এখনও স্ক্রিনে চলছে, এর প্যারেন্ট বাশ কোনও ইতিহাস পুনরায় পড়েনি:

  • পর্দায় পুনরায় সংযোগ
  • ^Zতারপর টিপুনup arrow
  • বোনাস: একক উদ্ধৃতিতে কমান্ডটি মোড়ুন (এর সাথে নেভিগেট ^A^A- কারণ স্ক্রিন (1) - এবং ^E) এবং প্রতিধ্বনি + একটি ফাইলে পুনঃনির্দেশ
  • fg কমান্ড কার্যকর করার জন্য

সাবধানতা অবলম্বন রয়েছে তবে বেশিরভাগ সময় এটি যথেষ্ট কার্যকর।


হ্যাঁ, এমনকি এটি হত্যা এবং টিপুন up। যদিও আপনার আত্মবিশ্বাস থাকতে হবে যে এটি কোনও সমস্যা ছাড়াই আবার শুরু হবে, তবে যদি তা না হয় তবে যাইহোক পুনরায় বুট করার পরে আপনার একই সমস্যা হবে। আপনার কেবলমাত্র আপনার মুহূর্তটি বেছে নিতে হবে যখন ডাউনটাইম কোনও সমস্যা হবে না।
ম্যাথিউ নাপোলি

0

আমি জানি আপনি নিজের উত্তরটি খুঁজে পেয়েছেন, তবে এমন কোনও কারণ আছে যা আপনি এরকম কিছু করতে পারবেন না:

(set -x; for f in 1 2 3 4 ; do  echo "$f"; sleep $f; done)

সম্ভবত আপনি প্রকৃত কাজের আউটপুট এবং ব্যাশ থেকে আউটপুট বর্তমানে নির্বাহকারী লাইন দেখায় একত্রীকরণ করতে পারবেন না।

এছাড়াও, FWIW, যদি আপনি ভার্বোসিটি পছন্দ করেন set -o xtrace,।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.