বাশ-এ শেষ কমান্ড থেকে আউটপুট পুনরায় ব্যবহার করা হচ্ছে


180

বাশ কমান্ডের আউটপুট কি কোনও রেজিস্টারে সংরক্ষিত আছে? যেমন $?প্রস্থান স্থিতির পরিবর্তে আউটপুট ক্যাপচার করার অনুরূপ কিছু similar

আমি একটি ভেরিয়েবলের সাথে আউটপুট নির্ধারণ করতে পারতাম:

output=$(command)

তবে এটি আরও টাইপিং ...


উত্তর:


184

আপনি ব্যবহার করতে পারেন $(!!) থেকে recompute (না পুনরায় ব্যবহার) গত কমান্ডের আউটপুট।

!!নিজস্ব, executes গত কমান্ড।

$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre

9
$(your_cmd)ব্যাকটিক্স ব্যবহার করে আপনি টাইপ করা থেকে নিজেকে বাঁচাতে পারেন : `your_cmd`জ্ঞানু বাশ ম্যানুয়াল অনুসারে তারা কার্যত অভিন্ন। অবশ্যই এটি @memecs

অনুশীলনে, কমান্ডের আউটপুট হ'ল নির্বিচারবাদী তাই আমি এটির পুনর্বিবেচনার জন্য কষ্ট পাব না। এটি অবশ্যই কার্যকর যখন আপনি এমন কিছু করতে চান git diff $(!!)যেখানে আগের কমান্ডটি একটি অনুরোধ ছিল find
শ্রীধর সারনোবাত

স্পষ্টতই $()ব্যাকটিকগুলির পরিবর্তে ব্যবহারের ভাল কারণ রয়েছে । তবে ঘুমোতে বোধহয় কিছুই নেই। github.com/koalaman/shellcheck/wiki/SC2006
মাইকেল ক্রেনশো

1
@ ইউজার 2065875 যদিও ব্যাকটিকগুলি এখনও ব্যাশে কাজ করে তবে তাদের পক্ষে অবমূল্যায়ন করা হয় $()
kurczynski

87

উত্তর না হয়। বাশ তার মেমরির কোনও পরামিতি বা কোনও ব্লকে কোনও আউটপুট বরাদ্দ করে না। এছাড়াও, আপনাকে কেবল বাশের অনুমতিপ্রাপ্ত ইন্টারফেস ক্রিয়াকলাপ দ্বারা অ্যাক্সেস করার অনুমতি দেওয়া হয়েছে। আপনি যদি এটি হ্যাক না করেন তবে বাশের ব্যক্তিগত ডেটা অ্যাক্সেসযোগ্য নয়।


2
প্রতিটি কমান্ডের আগে চলে এমন কিছু কাস্টম বাশ 'মিডলওয়্যার' ফাংশন রাখা কি সম্ভব, যেখানে এটির ফলে ফলাফলটি আউটপুটটিকে এমন কোনও কিছুর সাথে সংরক্ষণ করে যা বলে অভ্যন্তরীণ ক্লিপবোর্ড (বলুন, BASH_CLIPBOARD)?
প্যাট নিডহ্যাম

পছন্দ করুন লোডযোগ্য মডিউলগুলি পরীক্ষা করুন। আপনি একটি লিখতে পারেন কিনা দেখুন।
কনসোলবক্স

11

এটি করার একটি উপায় হ'ল ব্যবহার করে trap DEBUG:

f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG

এখন সর্বাধিক সম্পাদিত কমান্ডের স্টাডআউট এবং স্ট্ডার পাওয়া যাবে /tmp/out.log

কেবল খারাপ দিকটি হ'ল এটি একটি কমান্ড দু'বার কার্যকর করবে: একবার আউটপুট এবং ত্রুটি পুনর্নির্দেশ করতে /tmp/out.logএবং একবারে সাধারণভাবে। সম্ভবত এই আচরণটি রোধ করার কিছু উপায় রয়েছে।


10
সুতরাং আমি যখন টাইপ করব rm -rf * && cd .., কেবলমাত্র বর্তমান ডিরেক্টরিটিই নয়, তবে পিতামাতারও মুছে ফেলা হবে ?? এই পদ্ধতিটি আমার কাছে অত্যন্ত বিপজ্জনক বলে মনে হচ্ছে
ফিলি 294

1
এখন আমি কীভাবে এই ক্রিয়াটি পূর্বাবস্থায় ফেলি?
কার্তিক চৌহান

5
@KartikChauhan: শুধু কিtrap '' DEBUG
anubhava

7

আপনি যদি ম্যাক হয়ে থাকেন এবং কোনও ভেরিয়েবলের কাছে লেখার পরিবর্তে আপনার আউটপুট ক্লিপবোর্ডে সংরক্ষণ করতে কিছু মনে করেন না, আপনি পিবিসিপি এবং পিবিপাস্টকে একটি কর্মফল হিসাবে ব্যবহার করতে পারেন।

উদাহরণস্বরূপ, একটি ফাইল সন্ধান করার জন্য এটি করার পরিবর্তে এবং অন্য ফাইলের সাথে এর বিষয়বস্তুগুলি পৃথক করে:

$ find app -name 'one.php' 
/var/bar/app/one.php

$ diff /var/bar/app/one.php /var/bar/two.php

আপনি এটি করতে পারেন:

$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php

স্ট্রিংটি /var/bar/app/one.phpক্লিপবোর্ডে থাকবে যখন আপনি প্রথম কমান্ডটি চালাবেন।

উপায় দ্বারা, পিবি ইন pbcopyএবং pbpasteপেস্টবোর্ডের জন্য দাঁড়ান, ক্লিপবোর্ডের প্রতিশব্দ।


1
লিনাক্সে $ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
si-mikey

আকর্ষণীয়, আমি pbpasteকমান্ড প্রতিস্থাপনের সাথে একসাথে ব্যবহার করার কথা ভাবিনি ।
শ্রীধর সারনোবাত

আমি যদি প্রথমটি করি এবং পরে বুঝতে পারি যে এটি অদক্ষ ছিল, তবে দ্বিতীয় বিকল্পটির সাথে পুনরায় কাজ না করে আমি কীভাবে গণ্য সময়কে সঞ্চয় করব?
নেলসনগন

4

অনুভার উত্তর দ্বারা অনুপ্রাণিত, যা আমি মনে করি এটি আসলে গ্রহণযোগ্য নয় কারণ এটি প্রতিটি আদেশ দুটি বার চালায়।

save_output() { 
   exec 1>&3 
   { [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
   exec > >(tee /tmp/current)
}

exec 3>&1
trap save_output DEBUG

এইভাবে সর্বশেষ কমান্ডের আউটপুট / tmp / সর্বশেষে থাকে এবং কমান্ডটি দু'বার বলা হয় না।


1
আমি এটির একটি খারাপ দিক খুঁজে পেয়েছি এটি হ'ল আপনার কমান্ডগুলির মধ্যে কোনওটিই মনে করেন না যে তারা আর টিটিআইতে চলছে, যার অর্থ আপনার যে কোনও উপায়ে grepবা git diff+1 এর মতো রঙিন কোডগুলি কাজ করার জন্য বিশেষ মনোযোগের প্রয়োজন
মার্টি নেইল

2

কনসোলবক্সের মতোই বলেছে, আপনাকে ব্যাশ নিজেই হ্যাক করতে হবে। কেউ কীভাবে এটি অর্জন করতে পারে তার একটি দুর্দান্ত উদাহরণ এখানে । স্টারার্ড রেপোজিটরি (আসলে স্ট্যান্ডআউট রঙ করার জন্য বোঝানো হয়েছিল) এটি কীভাবে তৈরি করা যায় সে সম্পর্কে নির্দেশনা দেয়।

আমি চেষ্টা করে দেখলাম: কিছু নতুন ফাইল বর্ণনাকারীর .bashrcমতো পছন্দ করা

exec 41>/tmp/my_console_log

(নম্বর অবাধ হয়) এবং সংশোধন stderred.cতদনুসারে তাই কন্টেন্ট এছাড়াও 41. এটা FD লেখা পরার যে ধরনের কাজ করেন, কিন্তু NUL বাইট, অদ্ভুত formattings এবং মূলত বাইনারি ডেটা, পাঠযোগ্য নয় লোড ধারণ করে। হয়তো সি সম্পর্কে ভাল বোঝার সাথে কেউ চেষ্টা করে দেখতে পারেন।

যদি তা হয় তবে শেষ প্রিন্ট করা লাইনটি পেতে প্রয়োজনীয় সমস্ত কিছুই tail -n 1 [logfile]


1

হ্যাঁ, প্রতিটি সময় কেন অতিরিক্ত লাইন টাইপ করুন agreed আপনি ইনপুটটিতে ফিরে যাওয়া পুনর্নির্দেশ করতে পারেন, তবে আউটপুট ইনপুট (1> & 0) হ'ল না। এছাড়াও আপনি একই ফাইলের জন্য প্রতিটি ফাইলটিতে বারবার একটি ফাংশন লিখতে চাইবেন না।

আপনি যদি ফাইলগুলি কোথাও রফতানি না করে থাকেন এবং কেবল স্থানীয়ভাবে এটি ব্যবহারের উদ্দেশ্যে থাকেন তবে আপনার কাছে টার্মিনালটি ফাংশন ঘোষণার সেট আপ থাকতে পারে। আপনাকে ~/.bashrcফাইল বা ফাইলে ফাংশন যুক্ত করতে ~/.profileহবে। দ্বিতীয় ক্ষেত্রে, আপনি সক্ষম করতে হবে Run command as login shellথেকে Edit>Preferences>yourProfile>Command

একটি সহজ ফাংশন করুন, বলুন:

get_prev()
{
    # option 1: create an executable with the command(s) and run it
    echo $* > /tmp/exe
    bash /tmp/exe > /tmp/out

    # option 2: if your command is single command (no-pipe, no semi-colons), still it may not run correct in some exceptions
    #echo `$*` > /tmp/out

    # return the command(s) outputs line by line
    IFS=$(echo -en "\n\b")
    arr=()
    exec 3</tmp/out
    while read -u 3 -r line
    do
        arr+=($line)
        echo $line
    done
    exec 3<&-
}

মূল স্ক্রিপ্টে:

#run your command:
cmd="echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
get_prev $cmd
#or simply
get_prev "echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"

পূর্বের স্কোপের বাইরেও ব্যাশ ভেরিয়েবল সংরক্ষণ করে:

#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++)); do echo ${arr[i]}; done

1

খুব সহজ সমাধান

আমি বছরের পর বছর ধরে ব্যবহার করেছি।

স্ক্রিপ্ট (আপনার .bashrcবা যুক্ত করুন .bash_profile)

# capture the output of a command so it can be retrieved with ret
cap () { tee /tmp/capture.out}

# return the output of the most recent command that was captured by cap
ret () { cat /tmp/capture.out }

ব্যবহার

$ find . -name 'filename' | cap
/path/to/filename

$ ret
/path/to/filename

আমার | capসমস্ত কমান্ডের শেষের দিকে আমি যুক্ত হতে চাই। এইভাবে যখন আমি খুঁজে পাই আমি একটি ধীর চলমান কমান্ডের আউটপুটটিতে পাঠ্য প্রক্রিয়াকরণ করতে চাই আমি সর্বদা এটি দিয়ে পুনরুদ্ধার করতে পারি res


মানেটা কি এমন cat -মধ্যে cap () { cat - | tee /tmp/capture.out}এখানে? cap () { tee /tmp/capture.out }আমি মিস করছি এমন কোনও হিচাপ কি লাগবে?
ওয়াটসন

1
@ ওয়াটসন ভাল পয়েন্ট! আমি কেন জানি না কেন আমার সেখানে সম্ভবত সম্ভাবনা আছে। cat - | cat - | cat -এটিকে আরও আকর্ষণীয় করে তুলতে কি আমার আগেই যুক্ত করা উচিত ? Truly আমি সত্যই এটি ছড়িয়ে পড়েছে তা নিশ্চিত করার জন্য একবার এটি ঠিক করেছি
কনার

0

আপনার ঠিক কী জন্য এটি প্রয়োজন তা নিশ্চিত নন, সুতরাং এই উত্তরটি প্রাসঙ্গিক নাও হতে পারে। আপনি সর্বদা একটি কমান্ডের আউটপুট সংরক্ষণ করতে পারেন: netstat >> output.txtতবে আপনি যা সন্ধান করছেন তা আমি মনে করি না।

অবশ্যই প্রোগ্রামিং বিকল্প আছে; এই কমান্ডটি চালুর পরে আপনি কেবল উপরের টেক্সট ফাইলটি পড়ার জন্য একটি প্রোগ্রাম পেতে পারেন এবং এটি একটি ভেরিয়েবলের সাথে যুক্ত করতে পারেন এবং আমার পছন্দের ভাষা রুবিতে আপনি 'ব্যাকটিক্স' ব্যবহার করে কমান্ড আউটপুট থেকে একটি ভেরিয়েবল তৈরি করতে পারেন:

output = `ls`                       #(this is a comment) create variable out of command

if output.include? "Downloads"      #if statement to see if command includes 'Downloads' folder
print "there appears to be a folder named downloads in this directory."
else
print "there is no directory called downloads in this file."
end

এটি একটি .rb ফাইলে আটকে দিন ruby file.rbএবং এটি চালান: এবং এটি কমান্ডের বাইরে একটি ভেরিয়েবল তৈরি করবে এবং আপনাকে এটি পরিচালনা করতে দেবে।


9
"আপনার ঠিক এটির জন্য কী প্রয়োজন তা নিশ্চিত নন" ওয়েল, আপনি বলুন (যার দ্বারা আমি বলতে চাইছি ) একটি দীর্ঘ-সময়কালীন স্ক্রিপ্টটি চালিয়েছে, আউটপুট অনুসন্ধান করতে চাই এবং নির্বিকারভাবে নির্বাহের আগে আউটপুটটিকে পুনর্নির্দেশ করতে ভুলে গিয়েছিল। এখন আমি স্ক্রিপ্টটি পুনরায় চালু না করে আমার বোকামির প্রতিকারের চেষ্টা করতে চাই।
jscs

0

আমার একটি ধারণা আছে যে আমার সাথে সাথে বাস্তবায়নের চেষ্টা করার সময় নেই।

তবে আপনি যদি নীচের মতো কিছু করেন:

$ MY_HISTORY_FILE = `get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1 | tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!

আইও বাফারিংয়ে সমস্যা থাকতে পারে। ফাইলটি খুব বিশাল আকার ধারণ করতে পারে। এই সমস্যার সমাধান নিয়ে আসতে হবে।


0

আমি মনে করি স্ক্রিপ্ট কমান্ড ব্যবহার সাহায্য করতে পারে। কিছুটা এইরকম,

  1. স্ক্রিপ্ট -c বাশ-কিফএফ ফিফিটো_পিড

  2. বিশ্লেষণের পরে সেট করতে ব্যাশ বৈশিষ্ট্য ব্যবহার করা।


0

আপনি যদি পূর্ববর্তী কমান্ডটি পুনরায় সংশোধন করতে না চান আপনি একটি ম্যাক্রো তৈরি করতে পারেন যা বর্তমান টার্মিনাল বাফারটিকে স্ক্যান করে, শেষ কমান্ডটির -Suppised- আউটপুট অনুমান করার চেষ্টা করে, এটি ক্লিপবোর্ডে অনুলিপি করে এবং শেষ পর্যন্ত এটি টার্মিনালে টাইপ করে।

এটি সরল কমান্ডগুলির জন্য ব্যবহার করা যেতে পারে যা একক আউটপুট দেয় (উবুন্টুতে 18.04 এর সাথে পরীক্ষিত হয় gnome-terminal) return

ইনস্টল করুন নিম্নলিখিত সরঞ্জাম: xdootool, xclip,ruby

ইন gnome-terminalযান Preferences -> Shortcuts -> Select allএবং এটি সেট Ctrl+shift+a

নিম্নলিখিত রুবি স্ক্রিপ্ট তৈরি করুন:

cat >${HOME}/parse.rb <<EOF
#!/usr/bin/ruby
stdin = STDIN.read
d = stdin.split(/\n/)
e = d.reverse
f = e.drop_while { |item| item == "" }
g = f.drop_while { |item| item.start_with? "${USER}@" }
h = g[0] 
print h
EOF

কীবোর্ড সেটিংসে নিম্নলিখিত কীবোর্ড শর্টকাট যুক্ত করুন:

bash -c '/bin/sleep 0.3 ; xdotool key ctrl+shift+a ; xdotool key ctrl+shift+c ; ( (xclip -out | ${HOME}/parse.rb ) > /tmp/clipboard ) ; (cat /tmp/clipboard | xclip -sel clip ) ; xdotool key ctrl+shift+v '

উপরের শর্টকাট:

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