অবিলম্বে ("সুপার") শেলটিতে ফিরে না এসে প্রাথমিক কমান্ডগুলির সাথে একটি ইন্টারেক্টিভ বাশ সাবশেল চালান


86

আমি একটি বাশ সাবশেল চালাতে চাই, (1) কয়েকটি কমান্ড চালাচ্ছি, (2) এবং তারপরে আমি যেমন খুশি তাই করতে সাবস্কেলটিতে রয়েছি। আমি এগুলির প্রতিটি স্বতন্ত্রভাবে করতে পারি:

  1. -cপতাকা ব্যবহার করে কমান্ড চালান :

    $> bash -c "ls; pwd; <other commands...>"

    তবে কমান্ডগুলি কার্যকর করার পরে এটি তাত্ক্ষণিক "সুপার" শেলের কাছে ফিরে আসে। আমি কেবল একটি ইন্টারেক্টিভ সাবসেল চালাতে পারি:

  2. নতুন bashপ্রক্রিয়া শুরু করুন :

    $> bash

    এবং যতক্ষণ না আমি স্পষ্টভাবে বলি ততক্ষণ সাব-শেল থেকে বেরিয়ে আসবে না ... তবে আমি কোনও প্রাথমিক কমান্ড চালাতে পারি না। আমি সর্বাধিক সমাধান খুঁজে পেয়েছি:

    $> bash -c "ls; pwd; <other commands>; exec bash"

    যা কাজ করে, কিন্তু আমি যেভাবে চাইছিলাম তা নয়, কারণ এটি প্রদত্ত আদেশগুলি একটি সাবশেলে চালায় এবং তারপরে ইন্টারঅ্যাকশনের জন্য পৃথক একটি খুলবে।

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

এনবি: আমি যা জিজ্ঞাসা করছি না ...

  1. ব্যাশ ম্যান পৃষ্ঠাটি কোথায় পাবেন তা জিজ্ঞাসা করছেন না
  2. কোনও ফাইল থেকে কমান্ড আরম্ভ করার পদ্ধতি কীভাবে পড়বেন তা জিজ্ঞাসা করছেন না ... আমি কীভাবে এটি করব তা জানি, এটি সমাধান নয় যা আমি সন্ধান করছি
  3. tmux বা gnu স্ক্রিন ব্যবহারে আগ্রহী নয়
  4. এটি প্রসঙ্গে দিতে আগ্রহী না। অর্থাৎ, প্রশ্নটি কোনও সাধারণ উদ্দেশ্যে নয়, সাধারণ হিসাবে বোঝানো হয়েছে
  5. যদি সম্ভব হয়, তবে আমি যা চাই তা সম্পূর্ণ করতে চাই না, তবে একটি "নোংরা" উপায়ে কাজের চাপগুলি এড়াতে চাই। আমি কেবল একটি লাইনে এটি করতে চাই। বিশেষত, আমি এর মতো কিছু করতে চাই নাxterm -e 'ls'

আমি একটি প্রত্যাশা সমাধান কল্পনা করতে পারি, তবে এটি আপনার পছন্দ মতো ওয়ান-লাইনার খুব কমই। কীভাবে exec bashসমাধানটি আপনার পক্ষে অনুপযুক্ত?
গ্লেন জ্যাকম্যান

@glennjackman দুঃখিত, আমি জার্গনের সাথে পরিচিত নই। "প্রত্যাশা সমাধান" কী? এছাড়াও, exec bashসমাধানটিতে দুটি পৃথক সাবশেল জড়িত। আমি একটি অবিচ্ছিন্ন সাবশেল চাই।
সাব্বাতিনি লুকা

3
এর সৌন্দর্য এটি execহ'ল এটি প্রথম সাবশেলটিকে দ্বিতীয়টির সাথে প্রতিস্থাপন করে, তাই আপনি পিতামাতার নীচে কেবল 1 টি শেল রেখে গেছেন। যদি আপনার সূচনা কমান্ডগুলি পরিবেশের ভেরিয়েবল সেট করে, সেগুলি কার্যকর করা শেলের মধ্যে উপস্থিত থাকবে।
গ্লেন জ্যাকম্যান


2
এবং সমস্যাটি execহ'ল আপনি এমন কোনও কিছু হারিয়ে ফেলুন যা পরিবেশের মাধ্যমে সাব-শেলগুলিতে যেমন পাস করা হয়নি, যেমন- রফতানিবিহীন ভেরিয়েবল, ফাংশন, এলিয়াস, ...
কর্ট জে সাম্পসন

উত্তর:


77

এটি অস্থায়ী নামযুক্ত পাইপগুলির সাহায্যে সহজেই করা যায় :

bash --init-file <(echo "ls; pwd")

এই উত্তরটির জন্য ক্রেডিট লাই রায়ানের মন্তব্যে যায় । আমি এটি সত্যিই দরকারী বলে মনে করেছি এবং মন্তব্যগুলিতে এটি কম লক্ষণীয়, তাই আমি ভেবেছিলাম এটির নিজস্ব উত্তর হওয়া উচিত।


9
সম্ভবতঃ এর অর্থ এটি $HOME/.bashrcকার্যকর করা হয় না। এটি অস্থায়ী নামযুক্ত পাইপ থেকে অন্তর্ভুক্ত করতে হবে।
হুব্রো

9
স্পষ্ট করার জন্য, এর মতো কিছু:bash --init-file <(echo ". \"$HOME/.bashrc\"; ls; pwd")
হুব্রো

5
এটি এত স্থূল কিন্তু এটি কাজ করে। আমি বিশ্বাস করতে পারি না যে বাশ সরাসরি এটি সমর্থন করে না।
প্যাট নিমিমায়ার

2
@ গুস, .হ'ল sourceকমান্ডটির প্রতিশব্দ : ss64.com/bash/source.html
জোনাথন পটার

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

10

এটি একটি টেম্প ফাইলের সাথে রাউন্ডবাউটে উপায়ে করতে পারেন, যদিও এটিতে দুটি লাইন লাগবে:

echo "ls; pwd" > initfile
bash --init-file initfile

একটি দুর্দান্ত প্রভাবের জন্য আপনি টেম্প ফাইলটি এতে অন্তর্ভুক্ত করে নিজেকে মুছে ফেলতে rm $BASH_SOURCEপারেন।
এডুয়ার্ডো ইভানেক

এডুয়ার্ডো, আপনাকে ধন্যবাদ। এটি একটি দুর্দান্ত সমাধান, তবে ... আপনি কি বলছেন যে ফাইল I / O দিয়ে ফিডাল না করে এটি করা যায় না । আমি এটিকে স্ব-অন্তর্ভুক্ত কমান্ড হিসাবে রাখতে পছন্দ করব কেন তার স্পষ্ট কারণ রয়েছে কারণ মুহুর্তের ফাইলগুলি মিশ্রণে আসার সাথে সাথে আমাকে এলোমেলো টেম্প-ফাইলগুলি কীভাবে তৈরি করতে হবে তা নিয়ে চিন্তাভাবনা শুরু করতে হবে এবং তারপরে, যেমন আপনি উল্লেখ করেছেন, সেগুলি মুছে ফেলা হবে। যদি আমি কঠোর হতে চাই তবে এটিকে আরও অনেক বেশি প্রচেষ্টা দরকার। অতএব আরও নমনীয়, মার্জিত সমাধানের জন্য আকাঙ্ক্ষা।
সাব্বটিনি লুকা

1
@ সাবট্যাটিনিলুকা: আমি এরকম কিছু বলছি না। এটি কেবল একটি উপায়, এবং mktemp@ সিজেসি নির্দেশিত হিসাবে টেম্প ফাইল ফাইলটি সমাধান করে। বাশ স্টিডিনের সূচনা কমান্ডগুলি পড়তে সমর্থন করতে পারে তবে যতদূর আমি এটি বলতে পারি না। -Init ফাইল হিসাবে সুনির্দিষ্ট করা এবং সেগুলির অর্ধেক কাজ পাইপ করা হয় তবে বাশ তারপরে চলে যায় (সম্ভবত এটি পাইপলাইনটি সনাক্ত করেছে বলে)। মার্জিত সমাধান, আইএমএইচও, হ'ল এক্সিকিউটিভ ব্যবহার করা।
এডুয়ার্ডো ইভানেক

1
এটি কি আপনার সাধারণ ব্যাশ সূচনাটি ওভাররাইড করে না? @ সাব্বটিনিলুকা আপনি এটি অর্জনের জন্য কী চেষ্টা করছেন আপনি কেন একটি শেল অটো চালিয়ে কিছু কমান্ড চালাতে হবে এবং তারপরে খোলা রাখবেন?
ব্যবহারকারী 9517

11
এটি একটি পুরানো প্রশ্ন, তবে বাশ নীচের সিনট্যাক্স ব্যবহার করে অস্থায়ী নামযুক্ত পাইপ তৈরি করতে পারে: bash --init-file <(প্রতিধ্বনি "ls; pwd")।
মিথ্যা রায়ান

5

পরিবর্তে এটি চেষ্টা করুন:

$> bash -c "ls;pwd;other commands;$SHELL"

$SHELL এটি শেলটি ইন্টারেক্টিভ মোডে খোলা রাখে, সাথে সান্নিধ্যের জন্য অপেক্ষা করে exit


9
এফওয়াইআই, এটি পরে একটি নতুন শেল খুলবে, সুতরাং যদি কোনও কমান্ড বর্তমান শেলের অবস্থাকে প্রভাবিত করে (যেমন একটি ফাইলের
সসোর্সিং

3

আমি যে "প্রত্যাশা সমাধানটি" ​​উল্লেখ করছি সেটি হ'ল প্রত্যাশিত প্রোগ্রামিং ভাষার সাথে একটি ব্যাশ শেল প্রোগ্রামিং :

#!/usr/bin/env expect
set init_commands [lindex $argv 0]
set bash_prompt {\$ $}              ;# adjust to suit your own prompt
spawn bash
expect -re $bash_prompt {send -- "$init_commands\r"}
interact
puts "exiting subshell"

আপনি এই মত চালাতে চান: ./subshell.exp "ls; pwd"


আমার ধারণা, ইতিহাসেও কমান্ডগুলি নিবন্ধভুক্ত করার সুবিধা হবে, আমি কি ভুল করছি? এছাড়াও আমি আগ্রহী যদি বাশার্ক / প্রোফাইলটি এই ক্ষেত্রে কার্যকর করা হয়?
muhuk

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

1

নেটিভ সাবসেল ব্যবহার করবেন না কেন?

$ ( ls; pwd; exec $BASH; )
bar     foo     howdy
/tmp/hello/
bash-4.4$ 
bash-4.4$ exit
$

বন্ধনীগুলি দিয়ে কমান্ডগুলি আবদ্ধ করা বাশকে এই কমান্ডগুলি চালনার জন্য একটি সাবপ্রসেস তৈরি করে, সুতরাং আপনি উদাহরণস্বরূপ, প্যারেন্ট শেলকে প্রভাবিত না করে পরিবেশ পরিবর্তন করতে পারেন। এটি মূলত এর চেয়ে বেশি পঠনযোগ্য সমান bash -c "ls; pwd; exec $BASH"

যদি এটি এখনও ভার্বোজ দেখাচ্ছে, দুটি বিকল্প আছে। ফাংশন হিসাবে এই স্নিপেটটি হ'ল একটি:

$ run() { ( eval "$@"; exec $BASH; ) }
$ run 'ls; pwd;'
bar     foo     howdy
/tmp/hello/
bash-4.4$ exit
$ run 'ls;' 'pwd;'
bar     foo     howdy
/tmp/hello/
bash-4.4$ exit
$

আরেকটি হ'ল exec $BASHখাটো করা:

$ R() { exec $BASH; }
$ ( ls; pwd; R )
bar     foo     howdy
/tmp/hello/
bash-4.4$ exit
$

আমি ব্যক্তিগতভাবে Rঅ্যাপ্রোচটি বেশি পছন্দ করি , কারণ পালানোর স্ট্রিংগুলির সাথে খেলার দরকার নেই।


1
আমি নিশ্চিত নই যে দৃশ্যের জন্য ওপিকে মাথায় রাখার জন্য এক্সিকিউট ব্যবহার করে কোনও ক্যাথেটস রয়েছে কিনা, তবে আমার কাছে এটিই প্রস্তাবিত সর্বাধিক সেরা সমাধান, কারণ এতে কোনও স্ট্রিং এড়ানোর সমস্যা ছাড়াই প্লেইন বাশ কমান্ড ব্যবহার করা হয়।
পিটার

1

যদি sudo -E bashকাজ না করে তবে আমি নিম্নলিখিতটি ব্যবহার করি যা এখনও পর্যন্ত আমার প্রত্যাশা পূরণ করেছে:

sudo HOME=$HOME bash --rcfile $HOME/.bashrc

আমি হোম = $ হোম সেট করেছি কারণ আমি চাই যে আমার নতুন অধিবেশনটি রুট-এর হোমের পরিবর্তে আমার ব্যবহারকারীর হোমকে হোম সেট করতে হবে যা কিছু সিস্টেমে ডিফল্টরূপে ঘটে।


0

এর চেয়ে কম মার্জিত --init-file, তবে সম্ভবত আরও উপকারী:

fn(){
    echo 'hello from exported function'
}

while read -a commands
do
    eval ${commands[@]}
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.