আমি কতটা সাব-শেল গভীর তা কীভাবে জানব?


40

কখনও কখনও আমি যেমন ভিএম দিয়ে সাব-শেল শুরু করার মতো কাজ করি :sh। আমি কীভাবে জানব যে আমি যদি একটি সাব-শেলটিতে থাকি যেখানে exitকেবল আমাকে একটি স্তর ফিরিয়ে আনবে, বনাম the বহির্মুখী শেলের মধ্যে যেখানে exitআমাকে লগ আউট করবে বা আমার সেশনটি বন্ধ করবে।

আমি স্পিন করতে পারি এমন কিছু ধরণের ইনসেপশন টোটেম বা আমি কত স্তরের গভীর তা জানতে কিছু?



1
ওহে! আপনি একটি subshell অথবা নও হয় এক দ্রুত উপায় দেখতে echo $0। যদি এটি শীর্ষ স্তরের শেল হয় তবে এটি সম্ভবত ড্যাশ দিয়ে শুরু হবে। (এটি কমপক্ষে
ব্যাশের

উত্তর:


40

আপনি কমান্ডটি ব্যবহার করতে পারেন pstree(এটি উবুন্টু সহ ডিফল্টরূপে আসে)। উদাহরণস্বরূপ - বর্তমানে আমার ডাব্লুএসএলে একটিমাত্র খোলা টার্মিনাল উইন্ডো রয়েছে:

User@Wsl:~$ pstree
init─┬─init───bash───pstree
     └─{init}

User@Wsl:~$ bash
User@Wsl:~$ sh
$ bash
User@Wsl:~$ pstree
init─┬─init───bash───bash───sh───bash───pstree
     └─{init}

প্রকৃত লিনাক্স / উবুন্টু পরিবেশের মধ্যে প্রক্রিয়া গাছ আরও জটিল হবে। আমরা সেই বিকল্পটি দ্বারা গাছটিকে ফিল্টার করতে পারি -sযা একটি নির্বাচিত প্রক্রিয়াটির পিতামাতাকে দেখায়। সুতরাং আমাদের কমান্ডটি হতে পারে pstree -s $$, যেখানে $$পরিবেশের পরিবর্তনশীল যেখানে বর্তমান পিআইডি রয়েছে:

User@Ubuntu:~$ pstree -s $$
systemd──lightdm──lightdm──upstart──gnome-terminal-──bash──pstree

User@Ubuntu:~$ bash
User@Ubuntu:~$ sh
$ bash
User@Ubuntu:~$ pstree -s $$
systemd──lightdm──lightdm──upstart──gnome-terminal-──bash──bash──sh──bash──pstree

তথ্যসূত্র:


শেলের প্রম্পটে সূচক যুক্ত করুন: @ ওয়াল্টিনেটরের ধারণার ভিত্তিতে স্তরটি যখন একের চেয়ে গভীর হয় তখন প্রম্পটের সামনের দিকে একটি কাউন্টার রাখার জন্য আমি ডেমোটির নীচে প্রদর্শিত লাইনগুলি যুক্ত করেছি, প্রাসঙ্গিক রান কমান্ড ( ~/.*rc) ফাইলগুলির নীচে।

আমি ডাব্লুএসএল, উবুন্টু 16.04, উবুন্টু 18.04 (সার্ভার / ডেস্কটপ), উবুন্টু 19.04, জিনোম-টার্মিনাল, টিটি এবং এসএস সেশনের মধ্যে পরীক্ষা দিয়েছি। এখানে এটি কীভাবে কাজ করে:

এখানে চিত্র বর্ণনা লিখুন

সীমাবদ্ধতাটি হ'ল: ওএসের উপর নির্ভর করে কাউন্টারটি কেবল 13-14 মাত্রার গভীরতার জন্য কাজ করে। আমি কারণগুলি তদন্ত করার ইচ্ছা করি না :)

  • bash> .bashrc:

    DEPTH=$(($(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>') - 1))
    if (( DEPTH > 1 )); then PS1=$DEPTH:$PS1; fi
  • cshএবং tcsh> .cshrc:

    @ DEPTH = `pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'` - 0
    if ( $DEPTH > 1 ) then; set prompt="$DEPTH":"$prompt"; endif
  • zsh> .zshrc:

    DEPTH=$(($(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>') - 1))
    if (( DEPTH > 1 )); then PROMPT=$DEPTH:$PROMPT; fi
  • ksh> .kshrc:

    DEPTH=$(($(pstree -s $$ | sed -r 's/\-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>') - 0))
    if (( DEPTH > 1 )); then PS1="$DEPTH":"$PS1"'$ '; fi
  • shএটি আসলে dashউবুন্টুতে - এখানে জিনিসগুলি কিছুটা জটিল এবং তারযুক্ত (আরও তথ্যের জন্য নীচের উল্লেখগুলি পড়ুন):

    1. ~/.profileফাইলটি সম্পাদনা করুন এবং নীচে নীচের লাইনটি যুক্ত করুন:

      ENV=$HOME/.shrc; export ENV
    2. ~/.shrcনিম্নলিখিত বিষয়বস্তু দিয়ে ফাইলটি তৈরি করুন , নোটটি kshএতেও পড়বে $ENV:

      #!/bin/dash
      DEPTH=$(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>')
      if [ "$0" != 'ksh' ]; then DEPTH=$((DEPTH - 1)); fi
      if [ "$DEPTH" -gt 1 ]; then export PS1='$DEPTH:\$ '; fi

তথ্যসূত্র:


একটি কমান্ড তৈরি করুন যা গভীরতা আউটপুট করবে: আরেকটি বিকল্প হ'ল শেল কমান্ড তৈরি করা যা গভীরতা আউটপুট করবে। এই উদ্দেশ্যে এক্সিকিউটেবল ফাইল তৈরি করুন (সুতরাং এটি প্রসারণযোগ্য সিস্টেমের প্রশস্ত হওয়া উচিত):/usr/local/bin/depth

sudo touch /usr/local/bin/depth
sudo chmod +x /usr/local/bin/depth

আপনার প্রিয় সম্পাদকের সাহায্যে ফাইলটি সম্পাদনা করুন এবং নিম্নলিখিত বিষয়বস্তুগুলিকে এর সামগ্রী হিসাবে যুক্ত করুন:

#!/bin/bash

SHELLS='(bash|zsh|sh|dash|ksh|csh|tcsh)'
DEPTH=$(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec "\<$SHELLS\>")

if [[ $@ =~ -v ]]
then
        pstree -s $$ | sed -r 's/-+/\n/g' | grep -E "\<$SHELLS\>" | cat -n
fi

echo "DEPTH: $DEPTH"

[[ $DEPTH -gt 1 ]] && exit 0 || exit 1

উপরের স্ক্রিপ্টের দুটি বিকল্প রয়েছে -vবা --verboseএটি জড়িত শেলগুলির একটি তালিকা আউটপুট করবে। এবং অন্য একটি বিকল্প যা গভীরতার চেয়ে একের চেয়ে বেশি এবং এটির উপর ভিত্তি করে ফিরে আসবে exit 0বা তা পরীক্ষা করবে। exit 1সুতরাং আপনি এটিকে এটি ব্যবহার করতে পারেন depth && exit। এখানে ব্যবহারের কয়েকটি উদাহরণ দেওয়া হল:

User@Ubuntu:~$ depth          # we are at the 1st level - bash
DEPTH: 1
User@Ubuntu:~$ sh           
$ csh                         # we are at the 2nd level - dash
Ubuntu:~% depth               # we are at the 3rd level - csh
DEPTH: 3
Ubuntu:~% ksh
$ depth -v                    # we are at the 4th level - ksh
     1  bash
     2  sh
     3  csh
     4  ksh
DEPTH: 4
$ depth && exit               # exit to the 3rd level - csh
DEPTH: 4
Ubuntu:~% depth && exit       # exit to the 2nd level - dash
DEPTH: 3
exit
$ depth && exit               # exit to the 1st level - bash
DEPTH: 2
User@Ubuntu:~$ depth && exit  # stay at the 1st level - bash
DEPTH: 1
User@Ubuntu:~$ depth && exit  # stay at the 1st level - bash
DEPTH: 1

অন্যান্য সমাধানগুলির সাথে তুলনা: আমি এখানে সরবরাহিত পদ্ধতির কিছু দুর্বলতা খুঁজে পেতে কিছু অতিরিক্ত সময় ব্যয় করেছি। আমি নিম্নলিখিত দুটি ক্ষেত্রে কল্পনা করতে সক্ষম হয়েছি (আরও ভাল সিনট্যাক্স হাইলাইট করার জন্য মূল অক্ষরগুলি প্রয়োজন):

  • কখন suবা sudo -iজড়িত:

    User@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh|su|sudo)\>'
    1
    User@Ubuntu:~$ echo $SHLVL
    1
    User@Ubuntu:~$ depth
    DEPTH: 1
    
    User@Ubuntu:~$ su spas
    Password:
    
    Spas@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh|su|sudo)\>'
    1
    Spas@Ubuntu:~$ echo $SHLVL
    2
    Spas@Ubuntu:~$ depth
    DEPTH: 2
    
    Spas@Ubuntu:~$ sudo -i
    [sudo] password for spas:
    
    Root@Ubuntu:~# ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh|su|sudo)\>'
    3
    Root@Ubuntu:~# echo $SHLVL
    1
    Root@Ubuntu:~# depth
    DEPTH: 3
  • যখন সেখানে একটি পটভূমি প্রক্রিয়া চালু হয়:

    User@Ubuntu:~$ bash
    User@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'
    2
    User@Ubuntu:~$ echo $SHLVL
    2
    User@Ubuntu:~$ depth
    DEPTH: 2
    
    User@Ubuntu:~$ while true; do sleep 10; done &
    [1] 10886
    User@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'
    3
    User@Ubuntu:~$ echo $SHLVL
    2
    User@Ubuntu:~$ depth
    DEPTH: 2
    
    # Note: $SHLVL is not supported only by sh/dash.  
    #       It works with all other tested shells: bash, zsh, csh, tcsh, ksh
    
    User@Ubuntu:~$ sh
    $ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'
    4
    $ echo $SHLVL
    2
    $ depth
    DEPTH: 3

এখন আমি হতভম্ব হয়ে যাই আউটপুট সম্পর্কে আমি আমার সিস্টেমে করেছেন: systemd───xfce4-terminal───bash───pstree। কেন এটা এই উপায়?
Val

1
@val: systemd হ'ল init প্রক্রিয়া, অন্যান্য সমস্ত প্রক্রিয়ার পিতা-মাতা। আপনি স্পষ্টতই ব্যবহার করছেন xfce4-terminal, যা একটি bashশেল চালু করেছে, যার মধ্যে আপনি দৌড়েছিলেন pstree, যা নিজে এবং এর বাবা-মায়ের প্রতিবেদন করেছে। আপনি যদি সিস্টেমড এবং এক্সফেস 4-টার্মিনালের মধ্যে পদক্ষেপের অভাব বলতে চান তবে এটি হতে পারে যে xfce4- টার্মিনাল চালু করা কিছুতেই মারা গেছে বা অস্বীকার করেছে, সেক্ষেত্রে এটি init দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হবে।
নিক মাত্তিও

কোন কারণ না পড়লে SHLVL? প্রক্রিয়া এবং সিস্টেমের জুড়ে বহনযোগ্যতা, আমি ধরে নিই, তবে তারপরে pstree ইনস্টল করা নাও হতে পারে ..
ডি বেন নোবল

হ্যালো, @ ডি.বেইনকনবল, যেমন @ এমমন্টের উত্তরের অধীনে আলোচনা করা হয়েছে , $SHLVLকিছু শেল এটি সমর্থন করে না। আরও নির্দিষ্ট, উপরের ডেমো থেকে পরিবেশ অনুযায়ী এটি কেবল sh( dash) দ্বারা সমর্থিত নয় - এবং এই শেলটি এই পরিবর্তনশীল দ্বারা মোটেও গণনা করা হয় না। অন্যদিকে pstreeপ্যাকেজের অংশ psmisc এছাড়াও উপলব্ধ যে fuser, killallএবং অন্য কয়েকজন - এটা উবুন্টু প্রধান উপাদান - আমি ব্যবস্থা এই উত্তরটি উল্লেখ উপর এটি ইনস্টল করা হয়নি।
pa4080

30

SHLVLশেল ভেরিয়েবলের মান পরীক্ষা করুন :

echo $SHLVL

bashএর ম্যানুয়াল পৃষ্ঠা থেকে উদ্ধৃতি :

SHLVL  Incremented by one each time an instance of bash is started.

এটি দ্বারা সমর্থিত zsh


4
তবে sh গণনা করা হয় না, সুতরাং sh সহ প্রদত্ত উদাহরণটি SHLVL বৃদ্ধি পাবে না। তবুও, এটি এমন কিছু যা শেলগুলি খুব বেশি স্যুইচ না করে তাদের পক্ষে কার্যকর হতে পারে
ubfan1

3
@ ubfan1 যদি না ওভাররাইডিং ভিএমআরসি সংজ্ঞা :shথাকে তবে ব্যবহারকারীর লগইন শেলটিকে আমি ডিফল্ট মনে করি (এটি আসলে কোনও :shellনির্দিষ্ট শেল বাইনারিটির চেয়ে সংক্ষিপ্ত রূপ )
স্টিল্ড্রাইভার ২

3
আমি তেজ বিবরণ সাথে পরিচিত না, কিন্তু আমি আউট চেষ্টা করেছি :shথেকে vimএই উত্তর পোস্ট করার আগে, এবং এটা আমার জন্য শেল স্তর বৃদ্ধি করেনি। আমার লগইন শেল বাশ।
egmont

9

আমার মধ্যে .bashrc, আমি আমার পরিবর্তনশীল " " চিহ্নগুলিকে সংযোজন করে $SHLVLসামঞ্জস্য করতে ব্যবহার করি : $PS1+$SUBSHELL

...
# set a variable to reflect SHLVL > 1 (Ubuntu 12.04)
if [[ $SHLVL -gt 1 ]] ; then
    export SUBSHELL="${SUBSHELL:+$SUBSHELL}+"
else
    export SUBSHELL=""
fi
...

if [[ "$color_prompt" = yes ]]; then
#             chroot?                       Depth      green       user@host nocolor  :   green      $PWD  red      (status) off   $ or # space             
    PS1='${debian_chroot:+($debian_chroot)}${SUBSHELL}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[1;31m\]($?)\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}${SUBSHELL}\u@\h:\w\$ '
fi
...

তারপরে, আমি দেখতে পাচ্ছি যে আমি কত গভীর:

walt@bat:~(1)$ ed foo
263
!bash
+walt@bat:~(0)$ bash
++walt@bat:~(0)$ bash
+++walt@bat:~(0)$ exit
exit
++walt@bat:~(0)$ exit
exit
+walt@bat:~(0)$ exit
exit
!
q
walt@bat:~(0)$ 

4

awk:

# Count the occurrence of (sh)ells.
DEPTH_REGEX='^(ash|bash|busybox|csh|dash|fish|mksh|sh|tcsh|zsh)$'

DEPTH=$(/bin/ps -s $(/bin/ps -p $$ -osid --no-headers) -ocomm --no-headers | \
awk -v R=$DEPTH_REGEX '{for (A=1; A<=(NR-2); A++) {if ($A ~ R) {B++}}} END {print B}')

pgrep:

DEPTH=$(/usr/bin/pgrep -c -s $(/bin/ps -p $$ -osid --no-headers) '^(ash|bash|busybox|csh|dash|fish|mksh|sh|tcsh|zsh)$')

আপনি একটি ফাইলের মধ্যে দুটি সংস্করণের একটি রাখতে পারেন এবং source DEPTH উপলভ্য করতে উত্সটি ব্যবহার করতে পারেন।

# Set 256 colors in terminal.
if [ -x /usr/bin/tput ] && [ "$(SHELL=/bin/sh tput colors)" -ge 8 ]; then
    export TERM="xterm-256color"
fi

# change these if you don't dig my colors!

NM="\[\033[0;1;37m\]"   #means no background and white lines
HI="\[\033[0;37m\]"     #change this for letter colors
SI="\[\033[38;5;202m\]" #this is for the current directory
NI="\[\033[0;1;30m\]"   #for @ symbol
IN="\[\033[0m\]"

# Count the occurrence of (sh)ells.
source /usr/share/shell-depth/depth

PS1="${NM}[${HI}\u${NI}@${HI}\h ${SI}\w${NM} \A](${HI}${DEPTH}${NM}): ${IN}"

2

psপুরো শেল স্ট্যাকটি দেখতে (বর্তমান সহ) কোনও অতিরিক্ত যুক্তি ছাড়াই আপনি সহজেই ব্যবহার করতে পারেন। এটি আপনার psনিজের পাশাপাশি শুরু করা সমস্ত পটভূমির কাজগুলিও দেখানো হবে তবে আপনি কতটা গভীর তার মোটামুটি অনুমান দিতে পারে।


এটি উপরের উত্তরটি { echo hello world; ps; } &প্রমাণ করতে কাজ করে ps
WinEunuuchs2Unix

@ উইনউইউউচস ২ ইউনিক্স, আমি এর অর্থ কিছু বোঝাতে চাইছি: পেস্ট.বুন্টু.com
p

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