मैं सटीक कमांड लाइन को कुछ बैश उदाहरण के अंदर कैसे निष्पादित कर सकता हूं?


29

मेरे पास एक लंबे समय तक चलने वाला bashउदाहरण है (एक screenसत्र के अंदर ) जो लूप के अंदर कमांड के एक जटिल सेट को निष्पादित कर रहा है (प्रत्येक लूप के साथ पाइप, रीडायरेक्ट आदि)।

लंबी कमांड लाइन टर्मिनल के अंदर लिखी गई थी - यह किसी भी स्क्रिप्ट के अंदर नहीं है। अब, मुझे bash प्रक्रिया आईडी पता है, और मेरे पास रूट एक्सेस है - मैं सटीक कमांड लाइन को उसके अंदर निष्पादित कैसे देख सकता हूं 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'

क्या यह संभव है?

EDIT # 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

    यानी, ORIGINAL कमांड लाइन का कोई आउटपुट नहीं है, जो कि मैं खोज रहा हूं - यानी while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done

जवाबों:


40

मुझे पता था कि मैं तिनके पर लोभी था, लेकिन UNIX कभी विफल नहीं होता!

यहां बताया गया है कि मैंने इसे कैसे प्रबंधित किया:

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.Be 2 दिनों में ए को छोड़कर इसे चिह्नित करना सुनिश्चित करें।
स्लम

@ एस एल एम: धन्यवाद! मैं इसके बारे में एक ब्लॉग पोस्ट लिखूंगा - यह मजेदार था, इसे नीचे शिकार करना।
ttsiodras

1
साथ ReadLine सक्षम आप भी ऐसा कर सकते हैं gdb: print (char *)rl_line_buffer। एक अनुक्रम में वर्तमान कमांड है print (char *)the_printed_command। आप यह भी कर सकते हैं call history_builtin(), लेकिन यह बैश प्रक्रिया के tty पर आउटपुट होगा, इसलिए यह कम उपयोगी हो सकता है।
mr.spuratic

11
@ एसएलएम: विरोध नहीं कर सका - मैंने यहां इसके बारे में ब्लॉग किया: users.softlab.ece.ntua.gr/~ttsiod/bashheimer.html
ttsiodras

1
बैश धागा सुरक्षित है? आपको आशा है कि आप कुछ आंतरिक स्थिति को संशोधित नहीं कर रहे हैं जो वर्तमान में निष्पादित कोड को बढ़ाता है जब आप gdb से कुछ निष्पादित करते हैं। व्यवहार में, बैश लगभग निश्चित रूप से अपनी चाइल्ड प्रक्रिया के समाप्त होने का इंतजार कर रहा होगा जब भी आप इसे gdb के साथ निलंबित करेंगे।
एड्रियन प्रैंक

5

चूँकि कमांड अभी भी स्क्रीन में चल रहा है, इसलिए इसके पैरेंट बैश ने किसी भी इतिहास को दोबारा नहीं बनाया है:

  • स्क्रीन पर reattach
  • ^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)

शायद आप वास्तविक नौकरी के उत्पादन को कोस नहीं सकते हैं और वर्तमान में निष्पादित लाइन दिखा रहे हैं।

इसके अलावा, एफडब्ल्यूआईडब्ल्यू, यदि आप वर्बोसिटी पसंद करते हैं, तो set -o xtrace

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.