বাশার্কে [-n “$ PS1”] এর উদ্দেশ্য


10

কি উদ্দেশ্য করে [ -n "$PS1" ][ -n "$PS1" ] && source ~/.bash_profile;দাস? এই লাইনটি একটি মধ্যে অন্তর্ভুক্ত করা হয় .bashrcএকটি dotfiles এর রেপো

উত্তর:


20

এটি শেলটি ইন্টারেক্টিভ কিনা তা পরীক্ষা করে দেখছে। এই ক্ষেত্রে, ~/.bash_profileশেলটি ইন্টারেক্টিভ হলে কেবল ফাইলটি সোসিং করা হবে।

দেখুন "এই শেল ইন্টারঅ্যাকটিভ?" বাশ ম্যানুয়ালটিতে, যা নির্দিষ্ট আইডিয়মের উদ্ধৃতি দেয়। (এটি $-বিশেষ ভেরিয়েবলের iঅক্ষর রয়েছে কিনা তা পরীক্ষা করে শেলটি ইন্টারেক্টিভ কিনা তা যাচাই করারও পরামর্শ দেয় , যা এই সমস্যার আরও ভাল পদ্ধতির is


শ্যাশ ইন্টারেক্টিভ থাকলে কমপক্ষে বাশ PS1 এবং PS2 আনসেট করবে । আপনি নিজের জন্য এটি দেখতে পাচ্ছেন ( export PS1='abc$ '; bash -c 'echo "[$PS1]"' ), যা কেবল মুদ্রণ করে []। মনে হচ্ছে zsh অন্তত একটি পরীক্ষা থেকে একই কাজ করে না ... যাই হোক, উদ্দেশ্য এর [ -n "$PS1" ]কিনা শেল ইন্টারঅ্যাকটিভ বা না করা উচিত নয়।
ফিলাব্রেন্ডেন

3
এটি bashPS1 আনসেট করে যখন অ-ইন্টারেক্টিভ (আপনার পূর্ববর্তী মন্তব্যে টাইপ করা) একটি বাগ আইএমও হয়, পিএস 1 কোনও ব্যাশ-নির্দিষ্ট চলক নয়, এটি সেট করার কোনও ব্যবসা নেই। এটি একমাত্র শেল যা এটি করে (যদিও অ-ইন্টারেক্টিভ এমনকি এমনকি একটি ডিফল্ট মানকেও yashসেট PS1করে)।
স্টাফেন চেজেলাস

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

যদি আমি আরও নির্ভরযোগ্য বিকল্প প্রস্তাব করি (তবে বলুন [[ $- = *i* ]] && source ~/.bash_profile) আমি এই উত্তরটিকে আরও সম্পূর্ণ বিবেচনা করব ।
চার্লস ডাফি

@ চার্লসডফি স্পষ্টভাবে আমি মনে করি না যে এতে খুব বেশি ভুল হয়েছে [ -n "${PS1}" ], তবে আমি এখনও আমার উত্তরটি হাইলাইট করার জন্য আপডেট করেছি যে ব্যাশ ম্যানুয়ালটি $-শেলটি ইন্টারেক্টিভ কিনা তা নির্ধারণের জন্য পরিদর্শন করার পরামর্শ / পরামর্শ দেয় , আমি আশা করি আপনি উত্তরটি উন্নত করেছেন বলে খুঁজে পেয়েছেন। চিয়ার্স!
ফিলাব্রেন্ডেন

19

এটি কি করে

শেলটি ইন্টারেক্টিভ কিনা তা পরীক্ষা করার এটি একটি বিস্তৃত উপায়। সাবধান থাকুন যে এটি কেবল ব্যাশে কাজ করে, এটি অন্যান্য শেলগুলির সাথে কাজ করে না। সুতরাং এটি ঠিক আছে (মূর্খ হলে) .bashrcতবে এটি এতে কাজ করবে না .profile(যা sh দ্বারা পড়া হয়, এবং বাশ কেবলমাত্র শ এর সম্ভাব্য বাস্তবায়নগুলির মধ্যে একটি, এবং সবচেয়ে সাধারণ নয়)।

এটি কেন কাজ করে (কেবল বাশে!)

একটি ইন্টারেক্টিভ শেল শেল পরিবর্তনশীলকেPS1 ডিফল্ট প্রম্পট স্ট্রিংয়ে সেট করে । সুতরাং শেলটি যদি ইন্টারেক্টিভ থাকে PS1তবে সেট করা থাকে (যদি না ব্যবহারকারীরা .bashrcএটি সরিয়ে না ফেলে থাকে তবে এটি শীর্ষে এখনও ঘটতে পারে না .bashrc, এবং আপনি বিবেচনা করতে পারেন যে যাইহোক এটি করার মতো বোকামি জিনিস)।

কথোপকথনটি ব্যাশের ক্ষেত্রে সত্য: ব্যাশ আনসেটের অ-ইন্টারেক্টিভ দৃষ্টান্তগুলি PS1যখন তারা শুরু করে। লক্ষ্য করুন এই আচরণ ব্যাশ নির্দিষ্ট, এবং তর্কসাপেক্ষে একটি বাগ (কেন হবে bash -c '… do stuff with $var…'যখন কাজ করে না varহয় PS1?)। তবে বাশের সমস্ত সংস্করণ অবধি এবং 4.4 সহ (আমি লেখার মতো সর্বশেষ সংস্করণ) এটি করে।

অনেক সিস্টেম PS1পরিবেশে রফতানি করে। এটা একটা খারাপ ধারণা, কারণ বিভিন্ন শেল ব্যবহার PS1কিন্তু একটি ভিন্ন সিনট্যাক্স সঙ্গে (যেমন ব্যাশ এর প্রম্পট বেরিয়ে থেকে সম্পূর্ণরূপে ভিন্ন zsh এর প্রম্পট বেরিয়ে )। তবে এটি যথেষ্ট পরিমাণে বাস্তবে, PS1সেটটি দেখে এটি নির্ভরযোগ্য সূচক নয় যে শেলটি ইন্টারেক্টিভ। শেলটি PS1পরিবেশ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে ।

এটি কেন এখানে (ভুল) ব্যবহৃত হয়েছে

.bashrcপারস্পরিক ইন্টারেক্টিভ হওয়ার সময় ব্যাশ স্টার্টআপে পড়া ফাইল। একজন কম সুপরিচিত সত্য ব্যাশ এছাড়াও সার্চ করে .bashrcহয় একটি লগইন শেল এবং ব্যাশ এর হিউরিস্টিক উপসংহারে যে এই একটি দূরবর্তী অধিবেশন আছে (ব্যাশ চেক যদি তার পিতা বা মাতা হয় rshdবা sshd)। এই দ্বিতীয় ক্ষেত্রে, এটি PS1পরিবেশে সেট হওয়ার সম্ভাবনা নেই, কারণ কোনও ডট ফাইল এখনও চালানো হয়নি।

তবে কোডটি এই তথ্যটি যেভাবে ব্যবহার করে তা হ'ল বিপরীত counter

  • শেলটি যদি একটি ইন্টারেক্টিভ শেল হয়, তবে এটি .bash_profileসেই শেলের মধ্যে চলে । তবে .bash_profileলগইন-সময় স্ক্রিপ্ট। এটি এমন কিছু প্রোগ্রাম চালাতে পারে যা প্রতি সেশনে কেবল একবার চালানোর উদ্দেশ্যে করা হয়। এটি কিছু পরিবেশের ভেরিয়েবলগুলিকে ওভাররাইড করতে পারে যা ব্যবহারকারীরা শেলটি চালানোর আগে ইচ্ছাকৃতভাবে একটি অন্য মানতে সেট করেছিল। চলমান .bash_profileএকটি অ-লগ-ইন শেল মধ্যে সংহতিনাশক হয়।
  • শেলটি যদি অ ইন্টারেক্টিভ দূরবর্তী লগইন শেল হয় তবে এটি লোড হবে না .bash_profile। তবে এটি এমন ক্ষেত্রে যেখানে লোডিং .bash_profileদরকারী হতে পারে, কারণ একটি অ-ইন্টারেক্টিভ লগইন শেল স্বয়ংক্রিয়ভাবে লোড হয় না /etc/profileএবং ~/.profile

আমি মনে করি লোকেরা এটি করার কারণটি হ'ল জিইআইআই (খুব সাধারণ কেস) এর মাধ্যমে লগ ইন করা এবং যারা তাদের পরিবেশের পরিবর্তনশীল সেটিংসকে .bash_profileপরিবর্তে রাখে .profile। বেশিরভাগ জিইউআই লগইন প্রক্রিয়া আহ্বান করে .profileতবে তা হয় না .bash_profile(পড়ার .bash_profileজন্য অধিবেশন পরিবর্তে অধিবেশন শুরুর অংশ হিসাবে চলমান বাশ প্রয়োজন)। এই কনফিগারেশনের সাহায্যে, ব্যবহারকারী যখন কোনও টার্মিনাল খুলবে, তারা তাদের পরিবেশের ভেরিয়েবল পাবে। তবে, জিইউআই অ্যাপ্লিকেশনগুলিতে ব্যবহারকারীরা তাদের পরিবেশের পরিবর্তনশীলগুলি পাবেন না, যা বিভ্রান্তির একটি খুব সাধারণ উত্স। সমাধানটি পরিবেশের ভেরিয়েবলগুলি সেট করার .profileপরিবর্তে ব্যবহার করা .bash_profile। এর মধ্যে একটি ব্রিজ যুক্ত করা .bashrcএবং .bash_profileএটি সমাধানের চেয়ে আরও বেশি সমস্যার সৃষ্টি করে।

পরিবর্তে কি করতে হবে

বর্তমান শেলটি ইন্টারেক্টিভ কিনা তা পরীক্ষার একটি সরল, বহনযোগ্য উপায় রয়েছে: বিকল্পটি -iসক্ষম হয়েছে কিনা তা পরীক্ষা করুন ।

case $- in
  *i*) echo "This shell is interactive";;
  *) echo "This shell is not interactive";;
esac

এই দরকারী .bashrcথেকে পড়া .profileশুধুমাত্র যদি শেল অ ইন্টারঅ্যাকটিভ কি কোড আছে বিপরীত অর্থাৎ - পড়ুন .profileযদি ব্যাশ একটি (অ-ইন্টারেক্টিভ) লগ-ইন শেল, এবং এটা পড়া না যদি এটা একটি ইন্টারেক্টিভ শেল আছে।

if [[ $- != *i* && -r ~/.profile ]]; then . ~/.profile; fi

4
লক্ষ্য করার মতো বিষয় যে শেলটি ইন্টারেক্টিভ হলে পরীক্ষার আরও ভাল [[ -o interactive ]]উপায়টি (কেএসএইচ, বাশ, জেডএস) বা case $- in (*i*) ...; esac(পসিক্স) সাথে রয়েছে
স্টাফেন চেজেলাস

2
আমার বাশ (সংস্করণ 4.4.12) আসলে PS1ইন্টারেক্টিভভাবে চালিত না হলে আনসেট মনে হচ্ছে । এটি পরীক্ষার পক্ষে যথেষ্ট সহজ: আপনার ব্যাশ স্টার্টআপ ফাইলগুলিতে সেটটির মান মুদ্রণ করার PS1=cuckoo bash -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'সময় কোনও কিছু মুদ্রণ করবে না (এটি "কোকিল" স্ট্রিংটি প্রিন্ট করবে না)। PS1=cuckoo bash -i -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'$PS1
FooF

1
@ Stéphane Chazelas: POSIX প্রয়োজন হয় না যে $-রয়েছে iএকটি ইন্টারেক্টিভ শেল সঙ্গে।
সুদৃশ্য

1
Ksh এর সাথে সামঞ্জস্যপূর্ণ হওয়ার জন্য বোশ এটি ২০১২ সাল থেকে এটি করেন। আপনার উল্লেখ পরিবর্তনটি কার্যকর হওয়ার আগ পর্যন্ত এটি পসিক্স দ্বারা প্রয়োজনীয় ছিল না।
সুদৃশ্য

1
সত্যি বলতে গেলে , আমি বলব [ -n "${PS1}" ] ভুল বলা কিছুটা দূরে চলেছে, তারপরেই কেবল তখনই বিরতি ঘটে যখন কেউ পিএস 1 রফতানি করছে (যা আপনার উত্তরে আপনি বলেন যে এটি একটি খারাপ ধারণা এবং এমনকি এর কারণগুলিতেও যায়) এবং এটি প্রভাবিত করে না যাইহোক বাশ (যেহেতু এটি শেলটি অ-ইন্টারেক্টিভ হয় তবে এটি PS1 এবং PS2 আনসেট করে)) সম্ভবত "নিরুৎসাহিত" শব্দ ব্যবহার করা বা পদ্ধতির "সীমাবদ্ধতা" সম্পর্কে কথা বলাই ভাল হত। আমি মনে করি না এটি পুরোপুরি "ভুল"। যদি কিছু ভুল হয় তবে পিএস 1 রফতানি করছে, এটি অবশ্যই! যাইহোক, এর বিস্তারিত জানার জন্য ধন্যবাদ।
ফিলাব্রেন্ডেন

1

দেখে মনে হচ্ছে এই অদ্ভুত ধারণাটি bashপসিক্স শেল ক্লোন হিসাবে শুরু না হয়ে ক্লোন হিসাবে শুরু হওয়া থেকে শুরু করে Bourne Shell

ফলস্বরূপ, পসিএক্স ইন্টারেক্টিভ আচরণ ( $ENVইন্টারেক্টিভ শেলগুলির জন্য ডাকা হয়) পরে যুক্ত করা হয়েছে bashএবং এটি ব্যাপকভাবে পরিচিত নয়।

একটি শেল যা অনুরূপ আচরণকে মঞ্জুরি দেয়। এটি cshএবং csh অনুদানের $promptনির্দিষ্ট মান রয়েছে:

$prompt not set          non-interactive shell, test $?prompt.
$prompt set but == ""    .cshrc called by the which(1) command.
$prompt set and != ""    normal interactive shell.

তবে এটি না বোর্ন শেল বা পোসিক্স শেলগুলির ক্ষেত্রে প্রযোজ্য।

পসিক্স শেলের জন্য, কেবলমাত্র অনুমোদিত পদ্ধতি হ'ল ফাইলটিতে ইন্টারেক্টিভ শেলগুলির জন্য কোড স্থাপন করা:

$ENV

এটির একটি শেল নির্দিষ্ট নাম রয়েছে। এটা যেমন

$HOME/.kshrc    for the korn shell
$HOME/.bashrc   for bash
$HOME/.mkshrc   for mksh
$HOME/.shrc     for the POSIX Bourne Shell

অন্যান্য ব্যক্তিরা শেল পতাকা উল্লেখ করেছেন -i, তবে এটি নির্ভরযোগ্য প্রোগ্রামিংয়ের জন্য কার্যকর নয়। পসিক্সের জন্য এটির set -iজন্যও কাজ করা প্রয়োজন হয় না , বা $-এটিতে iইন্টারেক্টিভ শেলগুলির জন্য একটিও রয়েছে। পসিক্সের জন্য কেবল sh -iশেলটি ইন্টারেক্টিভ মোডে প্রয়োগ করা দরকার ।

যেহেতু ভেরিয়েবলটি $PS1পরিবেশ থেকে আমদানি করা যায়, অ-ইন্টারেক্টিভ মোডেও এর মান থাকতে পারে। সত্য যে bash unsetগুলি PS1কোন নন-ইন্টারেক্টিভ শেল আদর্শ দ্বারা অনুমোদিত না হয় এবং অন্য কোন শেল দ্বারা নয় সম্পন্ন।

সুতরাং পরিষ্কার প্রোগ্রামিং (এমনকি সহ bash) ইন্টারেক্টিভ শেলগুলির জন্য আদেশগুলি অন্তর্ভুক্ত করা $HOME/.bashrc


0

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

শেল স্টার্ট ফাইলগুলির সেটিংয়ে অনেক মতামত রয়েছে।
আমারও আমার মতামত আছে তবে আমি সঠিক সেটিংসের বিদ্যমান উদাহরণগুলি দেখানোর চেষ্টা করব।
এটির ফাইলগুলির উদাহরণগুলি পাওয়া খুব সহজ বলে আমি ডিবিয়ান ব্যবহার করব use
এবং ডেবিয়ানটি ভারী ব্যবহৃত হয়, তাই সেটিংসটি ভালভাবে পরীক্ষা করা হয়েছে,

পিএস 1 সেট করা আছে তা যাচাই করার লক্ষ্য কী?

কেবল শেলটি ইন্টারেক্টিভ কিনা তা খুঁজে বের করতে।

ডিফল্ট /etc/profileডেবিয়ান মধ্যে এবং উবুন্টু (থেকে, / usr / ভাগ / বেস-ফাইল / প্রফাইল):

if [ "${PS1-}" ]; then
    if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then

যদি পড়া হয়: ইন্টারেক্টিভ (পিএস 1 ডিফল্ট সেট) এবং এটি একটি বাশ শেল (তবে ডিফল্ট হিসাবে অভিনয় করছে না sh) তবে PS1 কে একটি নতুন নতুন (ডিফল্ট নয়) এ পরিবর্তন করুন।

ডিফল্ট /etc/bash.bashrcডেবিয়ান মধ্যে এছাড়াও রয়েছে:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

এটি যা করে তাতে কোনটি স্পষ্ট: যদি ইন্টারেক্টিভটি উত্স না করে (বাকী)।

যাইহোক, /etc/skel/.bashrcএকটি উদাহরণ (ব্যবহার করে একটি ইন্টারেক্টিভ শেল জন্য পরীক্ষার সঠিক উপায় $-):

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

এটি PS1 এবং কেন একটি বিকল্প স্পষ্টভাবে দেখা উচিত।

সঠিক অর্ডার

আপনি যে সেটিংটির প্রতিবেদন করছেন তা এড়ানো উচিত।
অর্ডার (সিস্টেম সেটিংস থেকে (ব্যাশ জন্য) আরও নির্দিষ্ট ব্যবহারকারী সেটিংস) হল /etc/profile, /etc/bash.bashrc, ~/.profileএবং পরিশেষে ~/.bashrc। এটি /etc/profile(যা মূলের মালিকানাধীন) এর পরে /etc/bash.bashrc(যা মূলের মালিকানাধীন ) সর্বাধিক বিস্তৃত প্রভাব (এবং আরও শাঁসের জন্য ) রাখে তবে কেবল বাশকেই প্রভাবিত করে। তারপরে ব্যক্তিগত সেটিংস আসুন $HOME, প্রথমটি ~/.profileবেশিরভাগ শাঁসের জন্য এবং ~/.bashrc(প্রায় সমতুল্য ~/.bash_profile), কেবল বাশের জন্য নির্দিষ্ট।

এটি উত্স ~/.bashrcথেকে ভুল তাই ~/.profileএটি ব্যাশের জন্য নির্দিষ্ট ব্যবহারকারী সেটিংসকে আরও সাধারণের দিকে রূপান্তর করছে যা আরও শেলকে প্রভাবিত করছেএইভাবে করা ছাড়া :

# ~/.profile: executed by the command interpreter for login shells
# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

এটি পরীক্ষা করে যে বাশ চলছে এবং কেবলমাত্র .bashrcযদি লোড হয় তবে তা লোড হয়।

এটি দেবিয়ান থেকে আগত একটি প্রবাহ সিদ্ধান্ত। যুক্তি এখানে ব্যাখ্যা করা হয়

আসলে, বিপরীত, গুন ~/.profileমধ্যে ~/.bash_profile(অথবা ~/.bashrc) শুধুমাত্র পুনরায় আবেদন সাধারণ নিয়ম যে ইতিমধ্যে একটি নির্দিষ্ট ব্যবহারের ক্ষেত্রে লোড করা উচিত হয়েছিল এবং সেইজন্য "নয় যে খারাপ" (আমি "ভালো" বলছি)। এবং আমি ভাল বলছি না কারণ এটি ফাইলগুলির স্যুরসিং লুপের কারণ হতে পারে। যেমন একটি উপ-ডিরেক্টরি যখন পিতামাতাকে বোঝায় তখন এটি ডিরেক্টরি লুপ।

এবং এই ক্রস সোর্সিং মধ্যে রয়েছে যে ইন্টারেক্টিভ শেলের জন্য চেকটি উপলব্ধি করে। কেবল যখন শেলটি ইন্টারেক্টিভ থাকে তখন ~/.bashrcলোড করা হয়, তবে এটি পরিবর্তিতভাবে লোড হতে পারে ~/.profile(বা অন্য কোনও উপায়ে) এবং এই ক্ষেত্রে ইন্টারেক্টিভ শেলটির জন্য পরীক্ষা করা ব্যবহার করা যেতে পারে।

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