කවචයක් පිවිසුම් / අන්තර්ක්‍රියාකාරී / කණ්ඩායමක් දැයි පරීක්ෂා කරන්නේ කෙසේද?


152

අන්තර්ක්‍රියාකාරී, පිවිසුම් සහ කණ්ඩායම් කවචයක් අතර ඇති වෙනස්කම් මට වැටහී ඇතැයි මම සිතමි. වැඩි උදව් සඳහා පහත සබැඳි බලන්න:

මගේ ප්‍රශ්නය නම්, මම අන්තර්ක්‍රියාකාරී, පිවිසුම් හෝ කණ්ඩායම් කවචයක සිටී නම් විධානයක් / කොන්දේසියක් සමඟ පරීක්ෂා කරන්නේ කෙසේද?

මම විධානයක් හෝ කොන්දේසියක් සොයමි (එය ආපසු trueහෝ false) සහ if ප්‍රකාශයක් මත තැබිය හැකිය. උදාහරණයක් වශයෙන්:

if [[ condition ]]
   echo "This is a login shell"
fi

3
තවත් ප්‍රශ්නයක් තිබේ: STDIN සහ / හෝ STDOUT tty (පර්යන්තය) හෝ පයිප්පයකට (ගොනුවක් හෝ ක්‍රියාවලියක්) සම්බන්ධ වී තිබේද? පහත දැක්වෙන සමහර අදහස් වල විස්තර කර ඇති පරිදි මෙය අදාළ නමුත් පැහැදිලි පරීක්ෂණයකි.
මාර්ක් හඩ්සන්

Answers:


172

bashටැග් වල ලැයිස්තුගත කර නොමැති නිසා මම ෂෙල් එකක් හෝ ඊට සමාන යැයි සිතමි .

ඔබ අන්තර්ක්‍රියාකාරී කවචයක සිටී දැයි පරීක්ෂා කිරීමට:

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'

ඔබ පිවිසුම් කවචයක සිටී දැයි පරීක්ෂා කිරීමට:

shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'

"කණ්ඩායම" මගින්, ඔබ අදහස් කරන්නේ "අන්තර්ක්‍රියාකාරී නොවේ", එබැවින් අන්තර්ක්‍රියාකාරී කවචයක් සඳහා වන චෙක්පත ප්‍රමාණවත් විය යුතුය.


16
සඳහා zshභාවිතා කරන්නන්, පිවිසුම් ෂෙල් සඳහා පරීක්ෂා සිදු කළ හැක:if [[ -o login ]] ...
chb

1
ඔබට දැන ගැනීමට අවශ්‍ය නම් “පරිශීලකයෙකු” ඔබේ වැඩසටහන “ක්‍රෝන්” ට එරෙහිව ක්‍රියාත්මක කළේද යන්න. [[ආමය == "ගොළු"]] && සුප්රසිද්ධ echo විධානය "ක්රොන් දී ධාවනය වෙමින් පවතී.
එරික් Aronesty

10
Ri එරික් ඇරොනෙස්ටි සියලුම ගොළු පර්යන්ත ක්‍රෝන් සැසි නොවේ.
ක්‍රිස් ඩවුන්

3
ටැග් වල කිසිදු කවචයක් ලැයිස්තුගත කර නොමැති බැවින් මම උපකල්පනය කරන්නේ බාෂ් කවචයක් හෝ ඊට සමාන ය. ” - මෙම ප්‍රකාශයේ තර්කනය සැබවින්ම ලස්සනයි! :)
මයිකල් ලෙ බාබියර් ග්‍රෙන්වාල්ඩ්

2
@antonio එයට හේතුව ඔබේ උපුටා දැක්වීම වැරදියි, $-වත්මන් කවචයේ පුළුල් වෙමින් පවතී. ඔබ සම්පූර්ණ ප්‍රකාශනය වටා තනි උපුටා දැක්වීම් භාවිතා කරන්නේ නම් ඔබට නිවැරදි bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'
ක්‍රිස් ඩවුන්

38

ඕනෑම බෝර්න් විලාසිතාවේ කවචයක, iවිකල්පය මඟින් කවචය අන්තර්ක්‍රියාකාරීද යන්න දක්වයි:

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

පිවිසුම් කවචයක් පරීක්ෂා කිරීම සඳහා අතේ ගෙන යා හැකි සහ සම්පූර්ණයෙන්ම විශ්වාසදායක ක්‍රමයක් නොමැත. Ksh සහ zsh එකතු lකරයි $-. Bash ඔබට විමසිය හැකි login_shellවිකල්පය සකසයි shopt -q login_shell. අතේ ගෙන යා හැකිදැයි පරීක්ෂා $0කරන්න -: ෂෙල් වෙඩි සාමාන්‍යයෙන් ඒවා පිවිසුම් කවච බව දන්නා නිසා ඇමතුම්කරු -තර්ක ශුන්‍යයට උපසර්ගයක් එක් කළ නිසා (සාමාන්‍යයෙන් ක්‍රියාත්මක කළ හැකි නම හෝ මාර්ගය). පුරනය වීමේ කවචයක් ආයාචනා කිරීමේ විශේෂිත ක්‍රම හඳුනා ගැනීමට මෙය අසමත් වේ (උදා ash -l).


(...) අමතන්නා - මම හිතන්නේ මේ කැබැල්ලේ යමක් නැතිවී ඇති බවයි.
පියොටර් ඩොබ්‍රොගොස්ට්

$0සෑම විටම එය ආරම්භ කළ -ආකාරය කුමක් වුවත් එය ආරම්භ වන්නේ නම් එය වඩාත් සුදුසු වේ. මෙම bash සැබෑ සෑම විටම නොවේ: එහෙත් අවම වශයෙන් එක් හැර ඇති වුවත් එය පිවිසුම් ෂෙල් විය කිරීමට නියමිත ව තිබේ. ඔබේ කොටුව තුළ එය උත්සාහ කරන්න: ආයාචනා කරන්න bash --login, පසුව $0තවමත් කියවන්න bash.
විරාවන් පර්වාන්ටෝ

Ira විරාවන්පූර්වන්ටෝ ඔබේ අදහස මට වැටහී ඇති බව මට විශ්වාස නැත. මගේ අන්තිම වාක්‍යයේ මා ලියා ඇත්තේ එය නොවේද?
ගිලෙස්ගේ SO- නපුරු වීම නවත්වන්න '

Il ගිලස්: ඔබ නිවැරදිය. කණගාටුයි මට ඔබේ අවසාන වාක්‍යය මග හැරුණි.
විරාවන් පර්වාන්ටෝ

24

මාළු කටුව

fishවෙනත් ඕනෑම පරිශීලකයෙක් මෙම පිටුවට බාධා කළහොත් පිළිතුර මෙන්න .

if status --is-interactive
    # ...
end

if status --is-login
    # ...
end

echo "darn, I really wanted to have to use globs or at least a case statement"

මාළු ලියකියවිලි: ආරම්භ කිරීම


3
-1 අනවශ්‍ය කතුවැකිය සඳහා.
නික් බැස්ටින්

8
@ නික්බැස්ටින්ගේ ප්‍රකාශය ගැන යමෙක් පුදුම වන්නේ නම්, ඔහුට සාධාරණ කරුණක් ඇති බැවින් මම සංස්කරණයක් කළෙමි. ගොළුබෙල්ලාගේ මුල් ප්‍රමාණය දැන් අඩකින් කපා ඇත.
ඔහ්ස්පයිට්

19

csh / tcsh

සඳහා cshසහ tcshමම මගේ පහත සඳහන් කර ඇත .cshrcගොනුව:

if($?prompt) then               # Only interactive shells set $prompt
    ...
endif

විෙශේෂෙයන් සඳහා tcsh, විචල්යය loginshපිවිසුම් කවචයක් සඳහා සකසා ඇත:

if($?loginsh) then              # A login shell..
    ...
endif

( tcshවිචල්‍යයක් ද ඇති අතර shlvlඑය කැදැලි කවච ගණනට සකසා ඇත, එහිදී පිවිසුම් කවචයේ අගය 1 වේ.)


2
PS1අන්තර්ක්‍රියාකාරී කවචයක් සඳහා පරීක්ෂා කිරීමට ක්‍රියා නොකරයි. එය සෑම විටම පාහේ අන්තර්ක්‍රියාකාරී ලෙස සකසා ඇත, නමුත් ඔබට එය සැකසිය නොහැක. බොහෝ පද්ධති සමඟ නැව් නිසා එය ඉතා බොහෝ විට මෙය noninteractive ෂෙල් සැකසූ export PSදී /etc/profile.
ගිලෙස්ගේ SO- නපුරු වීම නවත්වන්න '

@Gilles නිවැරදි සහ සංස්කරණය කිරීම සඳහා ඔබට ස්තුතියි
ඇන්ඩෲ ස්ටයින්

මෙය රන් ය: tcsh හි විචල්ය shlvl ද ඇති අතර එය කැදැලි කවච ගණනට සකසා ඇත, එහිදී පිවිසුම් කවචයේ අගය 1 වේ.
Israr

17

තවත් ක්‍රමයක් වන්නේ එහි ප්‍රති result ලය පරීක්ෂා කිරීමයි tty

if [ "`tty`" != "not a tty" ]; then

12
... හෝ [ -t 0 ]STDIN යනු tty එකක් දැයි පරීක්ෂා කිරීමට භාවිතා කරන්න. ඔබේ අවශ්‍යතා අනුව ඔබට 1 (STDOUT) හෝ 2 (STDERR) භාවිතා කළ හැකිය.
ඩෙරොබට්

@derobert - මට අලුත් දෙයක් පෙන්වීම ගැන ස්තූතියි
ඒඩ්‍රියන් කෝනිෂ්

11
මෙය වෙනස් පරීක්ෂණයකි. ආදාන අග්‍රයක් වන (ඔබ ටර්මිනලය තුළ ස්ක්‍රිප්ට් එකක් ධාවනය කරන ඕනෑම වේලාවක!) අන්තර්ක්‍රියාකාරී නොවන කවචයක් තිබිය හැකි අතර, ටර්මිනලයකින් නොව අන්තර්ක්‍රියාකාරී කවචයක් ලබා ගත හැකිය (දුර්ලභ වුවද).
ගිලෙස්ගේ SO- නපුරු වීම නවත්වන්න '

Il ගිල්ස් ෂෙල් එක අන්තර්ක්‍රියාකාරී නම් සහ දරුවෙකු අතහැර disownජීවත්ව සිටියදී වසා දැමුවහොත් ttyඑය තවදුරටත් අන්තර්ක්‍රියාකාරී නොවන බව දැන ගැනීමට වඩාත් සුදුසු විය $-. හොඳම ප්‍රවේශය කුමක්ද යන්න ගැන මම තවමත් ව්‍යාකූල වී සිටිමි.
ඇක්වාරියස් පවර්

5
QAquariusPower එවිට ඔබට පරීක්ෂා කිරීමට අවශ්‍ය වන්නේ අන්තර්ක්‍රියාකාරී කවචයක් සඳහා නොව සම්මත ආදානය පර්යන්තයක්ද යන්නයි. භාවිතා කරන්න [ -t 0 ]. PS මගේ පෙර අදහස් දැක්වීමේදී, “ශක්තිමත් සහසම්බන්ධයක් තිබේ” යනුවෙන් මා ලිවීය #!/bin/sh- අන්තර්ක්‍රියාකාරී නොවන නමුත් පර්යන්තයකට සම්බන්ධ කළ හැකි “ තිර රචනයක ආරම්භය හෝ ඒ හා සමාන අතිශයින්ම පොදු අවස්ථාව හැර” මට අමතක විය .
ගිලෙස්ගේ SO- නපුරු වීම නවත්වන්න '

10

ඔබ ටර්මිනලයක සිටීදැයි පරීක්ෂා කිරීමට යුනික්ස් / ලිනක්ස් වෙත විධානයක් ඇත.

if tty -s
then
echo Terminal
else
echo Not on a terminal
fi

1
මෙය ද ක්‍රියාත්මක වේ dash.
කෙන් ෂාප්

10

Stdin යනු පර්යන්තයක් දැයි බැලීමට ඔබට හැකිය:

if [ -t 0 ]
then
    echo "Hit enter"
    read ans
fi

3

ස්ක්‍රිප්ට් එකක් අන්තර්ක්‍රියාකාරී හෝ අන්තර්ක්‍රියාකාරී නොවන කවචයකින් ක්‍රියාත්මක වේදැයි පරීක්ෂා කිරීම සඳහා, $PS1විචල්‍යය තුළ ගබඩා කර ඇති විමසුමක් තිබේදැයි මම මගේ ස්ක්‍රිප්ට් පරීක්ෂා කරමි :

if [ -z $PS1 ] # no prompt?
### if [ -v PS1 ]   # On Bash 4.2+ ...
then
  # non-interactive
  ...
else
  # interactive
  ...
fi

මෙය මා මෙහි ඉගෙන ගත්තේ: https://www.tldp.org/LDP/abs/html/intandnonint.html


2

iසෙවීම සඳහා නිවැරදි විකල්පය නොවේ. -iවෙනත් ආකාරයකින් අන්තර්ක්‍රියාකාරී නොවන කවචයක් අන්තර්ක්‍රියාකාරී වීමට බල කිරීම. නිවැරදි ස්වයංක්‍රීයව ක්‍රියාත්මක කළ හැකි විකල්පය වන්නේ -s, නමුත් අවාසනාවකට මෙන් බාෂ් මෙය නිවැරදිව හසුරුවන්නේ නැත.

ඔබ $-සතුව තිබේද යන්න පරීක්ෂා කර බැලිය යුතුය s(මෙය ස්වයංක්‍රීයව ක්‍රියාත්මක කිරීමට අවසර දී ඇත) හෝ එහි අඩංගුද i(මෙය ස්වයංක්‍රීයව ක්‍රියාත්මක කිරීමට අවසර දී නැති නමුත් නිල වශයෙන් -iෂෙල් එකේ විධාන රේඛා විකල්පයට පමණක් සම්බන්ධ වේ ).


1
sෂෙල් එක stdin වෙතින් විධාන කියවන්නේ නම් එය අන්තර්ක්‍රියාකාරීද යන්න නොවේ. අන්තර්ක්‍රියාකාරී කවචයක් අනිවාර්යයෙන්ම stdin වෙතින් විධාන කියවන්නේ නැත (උත්සාහ කරන්න zsh -i < /dev/null, zsh මෙහි ව්‍යතිරේකය ලෙස පෙනුනද). කවචයක් යනු stdin වෙතින් විධාන කියවීම විය හැකි අතර අන්තර්ක්‍රියාකාරී නොවිය හැකිය (වැනි sh < fileහෝ echo 'echo "$1"' | sh -s foo bar).
ස්ටෙෆාන් චසෙලාස්

2
මට පෙන්වා දීමට අවශ්‍ය වූයේ මුල් බෝර්න් ෂෙල් එකෙහි i - හි 'i' නොමැති වීමයි, එය අන්තර්ක්‍රියාකාරී වීමට අදහස් කරන විට පවා.
schily

හරි, නමුත් යූ ඇන්ඩ් එල් හි “ෂෙල්” නවීන ෂෙල් වෙඩි වලට යොමු වේ . බෝර්න් කවචය සාමාන්‍යයෙන් ආධිපත්‍යයක් ලෙස සලකනු ලබන අතර ඔබ එය පැහැදිලි නොකරන්නේ නම් ඔබ කතා කරන්නේ කුමක් දැයි ජනතාව දැන ගනු ඇතැයි අපේක්ෂා කිරීමට තරම් ඔබේම ප්‍රභේදය ප්‍රධාන ධාරාව නොවේ. [[...]]Ksh / bash / zsh යන්නෙන් ගම්‍ය වන ප්‍රශ්නය සඳහන් වේ. ඔබ වැනි ස්ථානය තියෙනවා ඉතිහාසය සටහන් සඳහා පරීක්ෂා බව iතුළ $-ඇති Bourne ෂෙල් කැමැත්ත වැඩ නැහැ. නමුත් පසුව පරීක්ෂා කිරීම sවිශ්වාසදායක ලෙස ක්‍රියා නොකරනු ඇත. ඔබට පරීක්ෂා කිරීමට [ -t 0 ]හෝ i; එසේ වුවද එය කෙළවරේ ඇති අවස්ථා වලදී echo 'exec < /dev/tty; that-check' | sh'
රැවටෙනු ඇත

සොලාරිස් 10 දක්වා සොලාරිස් මුල් බෝර්න් ෂෙල් සමඟ එන අතර ප්‍රතිපත්ති පූජාවන්ට මූලිකත්වය දෙමින් ඇප්‍රොක්ස් ඇතුළත් වේ. SVr4 සිට කවචයේ ඇති දෝෂ 10 ක්. එබැවින් බෝර්න් ෂෙල් එකේ ඉඟියක් එක් කිරීම ඔබ විශ්වාස කළ හැකි තරම් රැවටිලිකාර නොවේ. අනෙක් පැත්තෙන් zsh ප්‍රමාණවත් තරම් නොගැලපේ, උදා: ඔබ zsh සමඟ "වින්‍යාස කිරීමට" උත්සාහ කරන විට එය අසාර්ථක වේ, එබැවින් zsh වෙත යොමු කිරීම සඳහා / bin / sh සැකසීමට පරෙස්සම් වන්න. BTW: අන්තර්ක්‍රියාකාරී වීමට තීරණය කළහොත් මගේ බෝර්න් ෂෙල් පෙරනිමියෙන් සකසයි.
schily

3
POSIX ට required - අවශ්‍ය නොවන බව මම දනිමි (එයට s අවශ්‍ය බව පෙනේ), මම ඔස්ටින් කාණ්ඩයේ ML මත ප්‍රශ්නය මතු කරමි.
ස්ටෙෆාන් චසෙලාස්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.