কীভাবে বাশকে অনুরোধ করা যায়, নতুন শেলের ভিতরে কমান্ড চালানো যায় এবং তারপরে ব্যবহারকারীকে নিয়ন্ত্রণ দেওয়া যায়?


86

এটি অবশ্যই সত্যিই সরল বা সত্যই জটিল হতে পারে তবে আমি এটি সম্পর্কে কিছুই খুঁজে পেলাম না ... আমি একটি নতুন বাশ উদাহরণ খুলতে চাইছি, তারপরে কয়েকটি কমান্ড চালাচ্ছি এবং তার ভিতরে থাকা ব্যবহারকারীকে নিয়ন্ত্রণ ফিরিয়ে দেব give একই উদাহরণ

আমি চেষ্টা করেছিলাম:

$ bash -lic "some_command"

তবে some_commandএটি নতুন উদাহরণের মধ্যে কার্যকর করে, তারপর এটি বন্ধ করে দেয়। আমি এটি উন্মুক্ত থাকতে চাই

উত্তরগুলির উপর প্রভাব ফেলতে পারে এমন আরও একটি বিবরণ: যদি আমি এটি কাজ করতে পারি তবে এটি আমার .bashrcউলাম (এস) হিসাবে ব্যবহার করব , সুতরাং aliasবাস্তবায়নের জন্য বোনাস পয়েন্ট !


এলিয়াসের শেষ অংশটি আমি বুঝতে পারি না। উপাত্তগুলি বর্তমান শেলের প্রসঙ্গে নির্বাহ করে, সুতরাং আপনি যে সমস্যাটি সমাধান করতে বলছেন তাতে তাদের সমস্যা নেই (যদিও বেশিরভাগ কারণেই, বেশ কয়েকটি কারণে অ্যালিয়াসের চেয়ে ফাংশনগুলি ভাল)।
ট্রিপলি

4
আমি alias shortcut='bash -lic "some_command"'আমার .bashrc এর মতো কিছু চালাতে সক্ষম হতে চাই তারপরে এটি চালানো shortcutএবং some_commandএটির মধ্যে ইতিমধ্যে চালিত একটি নতুন শেল রয়েছে ।
ফলিক্স সাপারেলি

উত্তর:


65
bash --rcfile <(echo '. ~/.bashrc; some_command')

অস্থায়ী ফাইলগুলি তৈরি করে enses অন্যান্য সাইটে প্রশ্ন:


আমি উইন্ডোজ 10 এ এটি করার চেষ্টা করেছি (একটি ব্যাচ "স্টার্টআপ" ফাইল / স্ক্রিপ্ট লেখার চেষ্টা করছি) এবং আমি পেয়েছিThe system cannot find the file specified.
ডাক্তার ব্লু

4
@ স্কট এটি ধাপে ধাপে ডিবাগ করুন: 1) cat ~/.bashrcকাজ করে? 2) cat <(echo a)কাজ করে? 3) bash --rcfile somefileকাজ করে?
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

4
@ স্কট আমরা কেবল ডাব্লুএসএলে এই সমস্যাটি ছড়িয়েছি (একটি স্টার্টআপ ব্যাচের ফাইল থেকে ব্যাশ চালু করছি)। আমাদের সমাধানটি কয়েকটি অক্ষর থেকে বাঁচতে হয়েছিল যাতে ব্যাচ এটি বুঝতে পারে: bash.exe --rcfile ^<^(echo 'source $HOME/.bashrc; ls; pwd'^)উইন্ডোজ কমান্ড প্রম্পট থেকে চালানো উচিত।
ব্যবহারকারী 2561747

সেখানে এটি যেমন ব্যবহারকারী স্যুইচিং সাথে কাজ করতে একটি উপায় আছে কি sudo bash --init-file <(echo "ls; pwd")বা sudo -iu username bash --init-file <(echo "ls; pwd")?
জেরেমিসপ্রোফাইল


40

এটি দেরি করে দেওয়া উত্তর, তবে আমার ঠিক একই সমস্যা ছিল এবং গুগল আমাকে এই পৃষ্ঠায় প্রেরণ করেছে, তাই সম্পূর্ণতার জন্য এখানে আমি কীভাবে সমস্যাটি ঘটিয়েছিলাম।

আমি যতদূর বলতে bashপারি, মূল পোস্টারটি যা করতে চেয়েছিল তা করার বিকল্প নেই। -cবিকল্প সবসময় পর কমান্ড মৃত্যুদন্ড কার্যকর করা হয়েছে ফিরে আসবে।

ভগ্ন সমাধান : এর চারপাশে সহজ এবং সুস্পষ্ট প্রচেষ্টা:

bash -c 'XXXX ; bash'

এটি আংশিকভাবে কাজ করে (অতিরিক্ত সাব-শেল স্তর সহ যদিও)। তবে সমস্যাটি হ'ল কোনও উপ-শেল যখন রফতানি পরিবেশের ভেরিয়েবলের উত্তরাধিকার সূত্রে প্রাপ্ত হয়, তবে উপাধি এবং ফাংশন উত্তরাধিকার সূত্রে প্রাপ্ত হয় না। সুতরাং এটি কিছু জিনিসের জন্য কাজ করতে পারে তবে সাধারণ সমাধান নয়।

আরও ভাল : এর চারপাশের উপায়টি হ'ল गतिशीलভাবে একটি স্টার্টআপ ফাইল তৈরি করা এবং এই নতুন ইনিশিয়েশন ফাইলের সাথে ব্যাশ কল করা, এটি নিশ্চিত করে যে আপনার নতুন থিম ফাইলটি আপনাকে ~/.bashrcপ্রয়োজনে নিয়মিত কল করে ।

# Create a temporary file
TMPFILE=$(mktemp)

# Add stuff to the temporary file
echo "source ~/.bashrc" > $TMPFILE
echo "<other commands>" >> $TMPFILE
echo "rm -f $TMPFILE" >> $TMPFILE

# Start the new bash shell 
bash --rcfile $TMPFILE

সুন্দর জিনিস হ'ল অস্থায়ী init ফাইলটি ব্যবহারের সাথে সাথেই নিজেকে মুছে ফেলবে, এটি সঠিকভাবে পরিষ্কার না হওয়ার ঝুঁকি হ্রাস করবে।

দ্রষ্টব্য: আমি নিশ্চিত নই / / ইত্যাদি / বাশক্রিকে সাধারণত একটি নন-লগইন শেলের অংশ হিসাবে ডাকা হয়। যদি তাই হয় তবে আপনি উত্স / ইত্যাদি / বাশার্কও চাইবেন আপনার ~/.bashrc


rm -f $TMPFILEজিনিস এটা তোলে। আমি এর জন্য আমার যে ব্যবহারের ক্ষেত্রে ছিল তা আমি মনে করি না এবং আমি এখন আরও উন্নত অটোমেশন কৌশল ব্যবহার করি, তবে এই পথেই!
ফলিক্স সাপরেলি

8
প্রক্রিয়া প্রতিস্থাপন সহ bash --rcfile <(echo ". ~/.bashrc; a=b")
কোনও টিএমপি

4
টেম্প ফাইলটি কেবল তখনই সাফ হবে যদি আপনার বাশ স্ক্রিপ্ট সফলভাবে চলতে থাকে। আরও দৃ solution় সমাধান ব্যবহার করা হবে trap
ট্রিপলি

5

--rcfileএটি আপনার পছন্দের একটি ফাইল পড়ার কারণ হিসাবে আপনি বাশে যেতে পারেন । এই ফাইলটি আপনার পরিবর্তে পঠিত হবে .bashrc। (যদি এটি কোনও সমস্যা ~/.bashrcহয় তবে অন্য স্ক্রিপ্টের উত্স ))

সম্পাদনা করুন: সুতরাং স্টাফ দিয়ে নতুন শেল শুরু করার জন্য একটি ফাংশন ~/.more.shদেখতে এরকম কিছু দেখাচ্ছে:

more() { bash --rcfile ~/.more.sh ; }

... এবং .more.shশেল শুরুর সাথে সাথে আপনি যে আদেশগুলি সম্পাদন করতে চান তা থাকতে পারে। (আমি মনে করি এটি আলাদা স্টার্টআপ ফাইল এড়াতে মার্জিত হবে - আপনি স্ট্যান্ডার্ড ইনপুট ব্যবহার করতে পারবেন না কারণ শেলটি ইন্টারেক্টিভ হবে না, তবে আপনি অস্থায়ী স্থানে এখানে একটি নথি থেকে একটি স্টার্টআপ ফাইল তৈরি করতে পারেন, তবে এটি পড়ুন))


3

স্ক্রিপ্টটি চালানোর পরিবর্তে আপনি যে কার্যকারিতাটি চান তা পেতে পারেন sour যেমন:

$ বিড়াল লিপি
সেমিডি 1
সেমিডি 2
। লিপি
point এই শেলটির ভিতরে এই মুহুর্তে cmd1 এবং cmd2 চালানো হয়েছে

হুঁ। এটি কাজ করে, তবে কোনও কিছুতে এম্বেড করার কোনও উপায় নেই alias=''?
ফলিক্স সাপরেলি

4
এলিয়াস কখনও ব্যবহার করবেন না; পরিবর্তে ফাংশন ব্যবহার করুন। আপনি রাখতে পারেন: 'foo () {সেমিডি 1; সেমিডি 2; start 'আপনার স্টার্ট আপ স্ক্রিপ্টগুলির ভিতরে, এবং তারপরে foo কার্যকর করা বর্তমান শেলটিতে দুটি কমান্ড চালাবে। মনে রাখবেন যে এই সমাধানগুলির কোনওটিই আপনাকে নতুন শেল দেয় না, তবে আপনি 'এক্সিকিউটিভ ব্যাশ' এবং তারপরে '
ফু

4
কখনও না বল না.
এলিয়াসদের

এমন কোনও ব্যবহারের ক্ষেত্রে উদাহরণ রয়েছে যেখানে কোনও উপামের পরিবর্তে কোনও ফাংশন ব্যবহার করা যায় না?
উইলিয়াম পার্সেল

3

এটির ~/.bashrcমতো একটি বিভাগে যুক্ত করুন :

if [ "$subshell" = 'true' ]
then
    # commands to execute only on a subshell
    date
fi
alias sub='subshell=true bash'

তারপরে আপনি সাবশেলটি শুরু করতে পারেন sub


মৌলিকতার জন্য পয়েন্টস। উপনামটি সম্ভবত সম্ভবত আরও ভাল env subshell=true bash(যেমন $subshellপরবর্তী কমান্ডগুলিতে ফাঁস হবে না ): রফতানি ব্যবহার করে এনভিভি বনাম ব্যবহার
ফলিক্স সাপরেলি

তুমি ঠিক. তবে আমি লক্ষ্য করেছি যে এটি ছাড়াও কাজ করে env। সংজ্ঞায়িত হয়েছে কি না তা যাচাই করার জন্য, আমি ব্যবহার করি echo $subshell(পরিবর্তে env | grep subshellআপনি ব্যবহার করেন)।
দশোহোকশা

3

গৃহীত উত্তর সত্যিই সহায়ক! কেবলমাত্র সেই প্রক্রিয়াটি যুক্ত করার জন্য <(COMMAND)কিছু শেল (যেমন, dash) সমর্থিত নয় ie

আমার ক্ষেত্রে, আমি শেল শুরু করতে এবং নির্বাচিত পাইথন ভার্চুয়াল পরিবেশ সক্রিয় করার জন্য থুনার ফাইল ম্যানেজারে একটি কাস্টম অ্যাকশন (মূলত একটি লাইন শেল স্ক্রিপ্ট) তৈরি করার চেষ্টা করছিলাম। আমার প্রথম প্রচেষ্টা ছিল:

urxvt -e bash --rcfile <(echo ". $HOME/.bashrc; . %f/bin/activate;")

%fথুনার পরিচালিত ভার্চুয়াল পরিবেশের পথটি কোথায় । আমি একটি ত্রুটি পেয়েছি (কমান্ড লাইন থেকে থুনার চালিয়ে):

/bin/sh: 1: Syntax error: "(" unexpected

তখন আমি বুঝতে পারি যে আমার sh(মূলত dash) প্রক্রিয়া প্রতিস্থাপন সমর্থন করে না।

আমার সমাধানটি ছিল bashঅতিরিক্ত স্তরের শেলের ব্যয়ে, প্রক্রিয়াটির বিকল্পটি ব্যাখ্যা করার জন্য শীর্ষ স্তরে প্রার্থনা করা:

bash -c 'urxvt -e bash --rcfile <(echo "source $HOME/.bashrc; source %f/bin/activate;")'

বিকল্পভাবে, আমি এখানে-নথি ব্যবহার করার চেষ্টা করেছি dashতবে কোনও সাফল্য নেই। কিছুটা এইরকম:

echo -e " <<EOF\n. $HOME/.bashrc; . %f/bin/activate;\nEOF\n" | xargs -0 urxvt -e bash --rcfile

পিএস: মন্তব্য পোস্ট করার মতো যথেষ্ট খ্যাতি আমার নেই, মডারেটররা দয়া করে এটিকে মন্তব্যগুলিতে স্থান দিতে বা এই প্রশ্নের সাথে সহায়ক না হলে এটিকে সরাতে দ্বিধা বোধ করবেন।


যদি কেউ শীর্ষে বাশ না চায় (বা এটি না থাকে), প্রক্রিয়া প্রতিস্থাপন সরাসরি প্রয়োগ করার বিভিন্ন নথিভুক্ত উপায় রয়েছে, বেশিরভাগই ফিফোস সহ।
ফলিক্স সাপরেলি

2

দাভেরজার উত্তর অনুসারে , এখানে একটি বাশ স্ক্রিপ্ট রয়েছে যা উদ্দেশ্যটি সমাধান করবে।

আপনি যদি সি-শেল ব্যবহার করে থাকেন এবং সি-শেল প্রসঙ্গে / উইন্ডোটি নীচে না রেখে কোনও কমান্ড কার্যকর করতে চান এমন পরিস্থিতিতে বিবেচনা করুন ,

মৃত্যুদন্ড কার্যকর করার নির্দেশ : কেবলমাত্র * .h, * .c ফাইলগুলিতে চলমান ডিরেক্টরিটিতে 'টেস্টিং' শব্দটির সন্ধান করুন

grep -nrs --color -w --include="*.{h,c}" Testing ./

সমাধান 1 : সি-শেল থেকে ব্যাশে প্রবেশ করুন এবং কমান্ডটি কার্যকর করুন

bash
grep -nrs --color -w --include="*.{h,c}" Testing ./
exit

সমাধান 2 : একটি পাঠ্য ফাইলে উদ্দেশ্যযুক্ত আদেশটি লিখুন এবং ব্যাশ ব্যবহার করে এটি সম্পাদন করুন

echo 'grep -nrs --color -w --include="*.{h,c}" Testing ./' > tmp_file.txt
bash tmp_file.txt

সমাধান 3 : ব্যাশ ব্যবহার করে একই লাইনে কমান্ড চালান

bash -c 'grep -nrs --color -w --include="*.{h,c}" Testing ./'

সমাধান 4 : একটি স্ক্রিপ্ট তৈরি করুন (এককালীন) এবং ভবিষ্যতের সমস্ত আদেশের জন্য এটি ব্যবহার করুন

alias ebash './execute_command_on_bash.sh'
ebash grep -nrs --color -w --include="*.{h,c}" Testing ./

স্ক্রিপ্টটি নিম্নরূপ:

#!/bin/bash
# =========================================================================
# References:
# https://stackoverflow.com/a/13343457/5409274
# https://stackoverflow.com/a/26733366/5409274
# https://stackoverflow.com/a/2853811/5409274
# https://stackoverflow.com/a/2853811/5409274
# https://www.linuxquestions.org/questions/other-%2Anix-55/how-can-i-run-a-command-on-another-shell-without-changing-the-current-shell-794580/
# https://www.tldp.org/LDP/abs/html/internalvariables.html
# https://stackoverflow.com/a/4277753/5409274
# =========================================================================

# Enable following line to see the script commands
# getting printing along with their execution. This will help for debugging.
#set -o verbose

E_BADARGS=85

if [ ! -n "$1" ]
then
  echo "Usage: `basename $0` grep -nrs --color -w --include=\"*.{h,c}\" Testing ."
  echo "Usage: `basename $0` find . -name \"*.txt\""
  exit $E_BADARGS
fi  

# Create a temporary file
TMPFILE=$(mktemp)

# Add stuff to the temporary file
#echo "echo Hello World...." >> $TMPFILE

#initialize the variable that will contain the whole argument string
argList=""
#iterate on each argument
for arg in "$@"
do
  #if an argument contains a white space, enclose it in double quotes and append to the list
  #otherwise simply append the argument to the list
  if echo $arg | grep -q " "; then
   argList="$argList \"$arg\""
  else
   argList="$argList $arg"
  fi
done

#remove a possible trailing space at the beginning of the list
argList=$(echo $argList | sed 's/^ *//')

# Echoing the command to be executed to tmp file
echo "$argList" >> $TMPFILE

# Note: This should be your last command
# Important last command which deletes the tmp file
last_command="rm -f $TMPFILE"
echo "$last_command" >> $TMPFILE

#echo "---------------------------------------------"
#echo "TMPFILE is $TMPFILE as follows"
#cat $TMPFILE
#echo "---------------------------------------------"

check_for_last_line=$(tail -n 1 $TMPFILE | grep -o "$last_command")
#echo $check_for_last_line

#if tail -n 1 $TMPFILE | grep -o "$last_command"
if [ "$check_for_last_line" == "$last_command" ]
then
  #echo "Okay..."
  bash $TMPFILE
  exit 0
else
  echo "Something is wrong"
  echo "Last command in your tmp file should be removing itself"
  echo "Aborting the process"
  exit 1
fi

4
এটি সম্পূর্ণ আলাদা সমস্যার সম্পূর্ণ ভিন্ন উত্তর। (এটি দুর্দান্ত যে আপনি এটি বুঝতে পেরেছেন, তবে এটি এই থ্রেডের সাথে অন্তর্ভুক্ত নয় this যদি এটি এই সাইটে উপস্থিত না থাকে তবে আপনার দ্বিতীয় বাক্যটি দিয়ে একটি নতুন প্রশ্ন খোলার বিষয়টি বিবেচনা করুন, তারপরে অবিলম্বে বাকীগুলির সাথে নিজেই উত্তর দিন ... এটিই কীভাবে পরিচালনা করা উচিত ☺) এছাড়াও কোনও টেম্প ফাইল তৈরি না করেই এটি করার উপায়ের জন্য সিরো সান্তিলির উত্তরটি দেখুন।
ফলিক্স সাপরেলি

উত্তর-উত্তর হিসাবে চিহ্নিত করা হয়নি, কারণ এটি এই প্রশ্নের উত্তর দেওয়ার চেষ্টা নয় (যদিও এটি ভিন্নর উত্তর দেওয়ার পক্ষে সত্যিই দুর্দান্ত চেষ্টা!)
চার্লস ডফি

0
$ bash --init-file <(echo 'some_command')
$ bash --rcfile <(echo 'some_command')

আপনি যদি প্রক্রিয়া প্রতিস্থাপন ব্যবহার করতে বা না করতে চান তবে:

$ cat script
some_command
$ bash --init-file script

অন্য উপায়:

$ bash -c 'some_command; exec bash'
$ sh -c 'some_command; exec sh'

shএকমাত্র উপায় ( dash, busybox):

$ ENV=script sh

ভাল বিকল্প, তবে উপরের অংশটির (অংশের আগে ENV=script) সরিয়ে দেওয়া বা পুনরায় উচ্চারণের অনুলিপিযুক্ত অনুলিপি-কপি পেস্টের সাথে বিভ্রান্ত হওয়া এড়ানোর জন্য উপকারী হবে ।
ফলিক্স সাপারেলি

@ ফলিকসাপারেল্লি সমস্ত সমাধানগুলি স্পষ্ট করে বলতে গেলে তবে ENV+ টি shঅন্য উত্তরগুলিতে উপস্থিত থাকে তবে বেশিরভাগ সংখ্যক পাঠ্যে দাফন করা হয় বা অপরিবর্তিত / অযৌক্তিক কোড দ্বারা ঘিরে রাখা হয়। আমি বিশ্বাস করি একটি সংক্ষিপ্ত, স্পষ্ট সংক্ষিপ্তসার থাকা প্রত্যেকের পক্ষে উপকারী হবে।
এক্স-ইউরি

0

এখানে আরও একটি (চলমান) বৈকল্পিক রয়েছে:

এটি একটি নতুন জিনোম টার্মিনাল খুলবে, তারপরে নতুন টার্মিনালে এটি ব্যাশ চালায়। ব্যবহারকারীর আরসি ফাইলটি প্রথমে পঠিত হয়, তারপরে ls -laইন্টারেক্টিভ পরিণত হওয়ার আগে নতুন শেলটিতে কার্যকর করার জন্য একটি কমান্ড প্রেরণ করা হয়। শেষ প্রতিধ্বনি এক্সিকিউশন শেষ করতে প্রয়োজনীয় একটি অতিরিক্ত নিউলাইন যুক্ত করে।

gnome-terminal -- bash -c 'bash --rcfile <( cat ~/.bashrc; echo ls -la ; echo)'

মাঝে মাঝে টার্মিনালটি সাজাতেও এটি দরকারী বলে মনে হয়, যেমন রঙের জন্য আরও ভাল দিকনির্দেশনা।

gnome-terminal --profile green -- bash -c 'bash --rcfile <( cat ~/.bashrc; echo ls -la ; echo)'

-1

পটভূমি শেলের কমান্ড কার্যকর করা হচ্ছে

&কমান্ডের শেষে কেবল যুক্ত করুন , যেমন:

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