Bash ස්ක්‍රිප්ට් එකකින් වැඩසටහනක් තිබේදැයි පරීක්ෂා කරන්නේ කෙසේද?


2226

දෝෂයක් නැවත ලබා දී පිටවීම හෝ ස්ක්‍රිප්ට් එක සමඟ ඉදිරියට යන ආකාරයකින් වැඩසටහනක් පවතින බව මා වලංගු කරන්නේ කෙසේද?

එය පහසු විය යුතු බවක් පෙනේ, නමුත් එය මට කඩුල්ලක් දමන ලදි.


"වැඩසටහනක්" යනු කුමක්ද? එයට කාර්යයන් සහ අන්වර්ථයන් ඇතුළත් වේද? whichමේවා සඳහා සත්‍ය වේ. typeතර්ක නොමැතිව අතිරේකව වෙන් කළ වචන සහ ෂෙල් බිල්ඩින් සඳහා සත්‍ය වේ. “වැඩසටහන” යන්නෙහි අර්ථය “නිදහසට කරුණක් $PATH” නම්, මෙම පිළිතුර බලන්න .
ටොම් හේල්

Answers:


3077

පිළිතුර

POSIX අනුකූල:

command -v <the_command>

Bash විශේෂිත පරිසරයන් සඳහා:

hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords

පැහැදිලි කිරීම

වළකින්න which. පමණක් නොව එය ඉතා මඳ වශයෙනි (වගේ builtins අර්ථය සඳහා ඔයා තමයි දියත් බාහිර ක්රියාවලිය hash, typeහෝ commandආකාරයකින් අඩු වේ), ඔබ ද ඇත්තටම ඔබට අවශ්ය දේ කිරීමට builtins විශ්වාසය තැබිය හැකි, බාහිර විධාන බලපෑම් පහසුවෙන් වෙනස් විය හැක අතර පද්ධතියට පද්ධතියට.

සැලකිලිමත් වන්නේ ඇයි?

  • බොහෝ මෙහෙයුම් පද්ධති ඇති whichබව පවා පිටවීම තත්ත්වය සකස් කරන්නේ නැහැ අර්ථය, if which fooපවා ක්රියාත්මක නොවන සහ කරන්නෙමි සෑම විටම බව වාර්තා fooඑය (සමහර POSIX කටු මෙය කිරීමට පෙනී බවයි සටහන් නොවේ පවා නම්, පවතී hashද).
  • බොහෝ මෙහෙයුම් පද්ධති whichමඟින් ප්‍රතිදානය වෙනස් කිරීම හෝ පැකේජ කළමණාකරු සමඟ සම්බන්ධ වීම වැනි අභිරුචි හා නපුරු දේ කරයි.

එබැවින් භාවිතා නොකරන්න which. ඒ වෙනුවට මේවායින් එකක් භාවිතා කරන්න:

$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }

(සුළු අතුරු සටහන: සමහර යෝජනා කෙරේ 2>&-සමාන වේ 2>/dev/nullනමුත් කෙටි - මෙම අසත්ය . 2>&-ස්ථාවර තැන්පතු 2 ක හේතු වන වැසුනු දෝෂයක් එය සාර්ථකව එය ලිඛිතව හා ප්රතිදාන ශක්තිය උපයෝගි වඩා බොහෝ වෙනස් වන, stderr වෙත ලිවීමට උත්සහ ගත් විට මෙම වැඩසටහන (හා භයානකයි!))

ඔබේ හැෂ් බැන්ග් /bin/shනම් ඔබ පොසික්ස් පවසන දේ ගැන සැලකිලිමත් විය යුතුය. typeසහ hashපිටවීමේ කේත POSIX විසින් ඉතා හොඳින් අර්ථ දක්වා hashනොමැති අතර, විධානය නොපවතින විට එය සාර්ථකව පිටවන බව පෙනේ (මෙය typeතවම දැක නැත). commandපිටවීමේ තත්වය POSIX විසින් මනාව නිර්වචනය කර ඇති අතර එමඟින් භාවිතා කිරීමට වඩාත්ම ආරක්ෂිත වේ.

ඔබේ තිර රචනය භාවිතා නම් bashවුවත්, POSIX නීති තවදුරටත් ඇත්තටම වැඩක් නෑ දෙකම typeහා hashභාවිතා කිරීම සම්පූර්ණයෙන්ම ආරක්ෂිත බවට පත් වේ. typeදැන් මේ -Pහුදෙක් සෙවීමට PATHහා hashවිධානය පිහිටීම සාමාන්යයෙන්, ඔබට මීට ඇත්තටම එය භාවිතා කිරීමට නම් එහි පැවැත්ම සඳහා පරීක්ෂා සිට හොඳ දෙයක් වන වන, hashed කරන බව (වේගවත් ඉදිරි කාලය ඔබ එය භාවිතා විමසුම් සඳහා) පැත්තේ-බලපෑමක් ඇති කොට ඇත .

සරල උදාහරණයක් ලෙස, ශ්‍රිතයක් තිබේ gdateනම් එය ක්‍රියාත්මක වේ, එසේ නොමැති නම් date:

gnudate() {
    if hash gdate 2>/dev/null; then
        gdate "$@"
    else
        date "$@"
    fi
}

සම්පූර්ණ විශේෂාංග කට්ටලයක් සමඟ විකල්ප

ඔබේ අවශ්‍යතාවය සපුරාලීම සඳහා පොදු-ස්ක්‍රිප්ට් භාවිතා කළ හැකිය .

යමක් ස්ථාපනය කර ඇත්දැයි පරීක්ෂා කිරීමට, ඔබට මෙය කළ හැකිය:

checkBin <the_command> || errorMessage "This tool requires <the_command>. Install it please, and then run this tool again."

35
EGeert: 'foo' නොපවතින විට &> / dev / null කොටස 'වර්ගය' යන පණිවිඩය සඟවයි. දෝංකාරය මත ඇති & 2 සම්මත ප්‍රතිදානය වෙනුවට දෝෂ පණිවිඩය සම්මත දෝෂයකට යැවීමට වග බලා ගනී; මොකද ඒක සම්මුතියක්. ඒවා දෙකම ඔබගේ පර්යන්තයේ දිස් වේ, නමුත් සම්මත දෝෂය අනිවාර්යයෙන්ම දෝෂ පණිවිඩ සහ අනපේක්ෂිත අනතුරු ඇඟවීම් සඳහා වඩාත් කැමති ප්‍රතිදානය වේ.
ලූනාත්

6
-P ධජය 'sh' හි ක්‍රියා නොකරයි, උදා: stackoverflow.com/questions/2608688/…
momeara

130
'උසස්' අයි / ඕ යළි හරවා යැවීම ගැන නුහුරු අය සඳහා: 1) 2>&- ("සමීප නිමැවුම් ගොනු විස්තර 2, එය stderr වේ) සමාන ප්‍රති result ල ඇත 2> /dev/null; 2) >&2සඳහා 1>&2වන කෙටිමඟකි, එය "stdout to stderr වෙත හරවා යැවීම" ලෙස ඔබ හඳුනාගත හැකිය. වැඩි විස්තර සඳහා උසස් බෑග් ස්ක්‍රිප්ටින් මාර්ගෝපදේශය i / o යළි-යොමුවීම් පිටුව බලන්න .
මයික්වෝටර්

9
ikemikewaters ඒබීඑස් තරමක් දියුණු පෙනුමක් ඇති අතර පුළුල් පරාසයක බාෂ් සහ බාෂ් නොවන සීඑල්අයි ක්‍රියාකාරිත්වය විස්තර කරයි, නමුත් එය බොහෝ අංශවල ඉතා නොසැලකිලිමත් වන අතර හොඳ පුරුදු අනුගමනය නොකරයි. මෙම අදහස් දැක්වීමේදී මට ලිවීමට තරම් ඉඩක් නොමැත; නමුත් මම නරක කේතය අහඹු උදාහරණ කිහිපයක් ඇලවිය හැකි: while read element ; do .. done <<< $(echo ${ArrayVar[*]}), for word in $(fgrep -l $ORIGINAL *.txt), ls -l "$directory" | sed 1d , {{දී සඳහා seq $BEGIN $END}}, ... බොහෝ කතුවරුන් හා සම්බන්ධ කිරීම සහ වැඩි දියුණු යෝජනා කරනවා කිරීමට උත්සාහ කර ඇති නමුත් එය කිසිදු විකි හා ඉල්ලීම් බිහිරි කන් මත ගොඩ බානු ඇත තියෙන්නේ.
lhunath

56
@mikewaters 2>&-වේ නොහැකි ලෙස එම 2>/dev/null. පළමුවැන්නා ගොනු විස්තරය වසා දමයි, දෙවැන්න එය වෙත හරවා යවයි /dev/null. ඔබට දෝෂයක් නොපෙනෙන්නට පුළුවන.
nyuszika7h

583

පහත දැක්වෙන්නේ විධානයක් තිබේද $PATH සහ ක්‍රියාත්මක කළ හැකිද යන්න පරීක්ෂා කිරීම සඳහා ගෙන යා හැකි ක්‍රමයකි :

[ -x "$(command -v foo)" ]

උදාහරණයක්:

if ! [ -x "$(command -v git)" ]; then
  echo 'Error: git is not installed.' >&2
  exit 1
fi

ක්‍රියාත්මක කළ හැකි චෙක්පතක් අවශ්‍ය වන්නේ එම නම සහිත ක්‍රියාත්මක කළ හැකි ගොනුවක් සොයාගත නොහැකි නම් බාෂ් විසින් ක්‍රියාත්මක කළ නොහැකි ගොනුවක් ලබා දෙන $PATHබැවිනි.

ක්‍රියාත්මක කළ නොහැකි ගොනුවක් කලින් ක්‍රියාත්මක කළ හැකි නමක් ඇති නම් $PATH, ඉරක් ක්‍රියාත්මක කළත්, ඩෑෂ් විසින් පෙර සඳහන් කරයි. මෙය දෝෂයක් වන අතර එය POSIX ප්‍රමිතිය උල්ලං in නය කිරීමකි. [ දෝෂ වාර්තාව ] [ සම්මත ]

ඊට අමතරව, ඔබ සොයන විධානය අන්වර්ථයක් ලෙස අර්ථ දක්වා ඇත්නම් මෙය අසාර්ථක වනු ඇත.


4
ඇත command -vපවා-ක්රියාකාරී නොවන ගොනුව සඳහා මාර්ගය නිෂ්පාදනය? එනම්, -x සැබවින්ම අවශ්‍යද?
einpoklum

5
-xගොනුව ක්‍රියාත්මක කළ හැකි බව pinpoklum පරීක්‍ෂා කරයි, ප්‍රශ්නය එයයි.
කෙන් ෂාප්

3
En කෙන්ෂාර්ප්: නමුත් එය අතිරික්තයක් ලෙස පෙනේ, මන්ද commandඑය ක්‍රියාත්මක කළ හැකි දැයි පරීක්ෂා කරනු ඇත - එසේ නොවේ ද?
einpoklum

13
ineinpoklum ඔව්, එය අවශ්‍යයි. ඇත්ත වශයෙන්ම, මෙම විසඳුම පවා එක් අද්දරකින් කැඩී යා හැක. මෙය මගේ අවධානයට යොමු කිරීම ගැන ස්තූතියි. dash, bash, සහ zsh සියල්ලම $PATHවිධානයක් ක්‍රියාත්මක කිරීමේදී ක්‍රියාත්මක කළ නොහැකි ගොනු මඟ හරින්න . කෙසේ වෙතත්, හැසිරීම command -vඉතා නොගැලපේ. ඉරක් තුළ, එය $PATHක්‍රියාත්මක කළ හැකිද නැද්ද යන්න නොසලකා පළමු ගැලපෙන ගොනුව නැවත ලබා දෙයි . බාෂ් වලදී, එය පළමු ක්‍රියාත්මක කළ හැකි තරගය නැවත ලබා දෙයි $PATH, නමුත් කිසිවක් නොමැති නම්, එය ක්‍රියාත්මක කළ නොහැකි ගොනුවක් ආපසු ලබා දිය හැකිය. Zsh හි, එය කිසි විටෙකත් ක්‍රියාත්මක කළ නොහැකි ගොනුවක් ලබා නොදේ.
nyuszika7h

5
මට කිව හැකි පරිදි, dashපොසික්ස් නොගැලපෙන එම තුනෙන් එකම එක; [ -x "$(command -v COMMANDNAME)"]අනෙක් දෙකෙහි වැඩ කරනු ඇත. මෙම දෝෂය දැනටමත් වාර්තා වී ඇති නමුත් තවමත් කිසිදු ප්‍රතිචාරයක් ලැබී නැති බව පෙනේ
nyuszika7h

210

භාවිතය අධෛර්යමත් කිරීම සඳහා මම ලූනාත් සමඟ එකඟ whichවන අතර ඔහුගේ විසඳුම බාෂ් භාවිතා කරන්නන් සඳහා සම්පූර්ණයෙන්ම වලංගු වේ . කෙසේ වෙතත්, වඩා අතේ ගෙන යා හැකි නම්, command -vඒ වෙනුවට භාවිතා කළ යුතුය:

$ command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed.  Aborting." >&2; exit 1; }

විධානය commandPOSIX අනුකූල වේ. එහි පිරිවිතර සඳහා මෙහි බලන්න: විධානය - සරල විධානයක් ක්‍රියාත්මක කරන්න

සටහන: typePOSIX අනුකූල වේ, නමුත් type -Pඑසේ නොවේ.


3
ඉහත ආකාරයටම - exit 1;එතැන් සිට ආයාචනා කළහොත් xterm එකක් මරා දමයි.
පරිශීලකයා නොදන්නා

1
මෙය සම්මත sh මත ක්‍රියා නොකරනු ඇත: ඔබ &> වලංගු යළි-යොමුවීම් උපදෙස් නොවේ.
jyavenard

7
yjyavenard: ප්‍රශ්නය ටැග් කර ඇත්තේ bash , එබැවින් වඩාත් සංක්ෂිප්ත bash- විශේෂිත යළි-යොමුවීම් අංකනය &>/dev/null. කෙසේ වෙතත්, මම ඔබ සමඟ එකඟ වෙමි, සැබවින්ම වැදගත් වන්නේ අතේ ගෙන යා හැකි හැකියාවයි, මම ඒ අනුව මගේ පිළිතුර සංස්කරණය කළෙමි, දැන් සම්මත sh යළි-යොමුවීම් භාවිතා කරමි >/dev/null 2>&1.
ග්‍රෙග්වී

මෙම පිළිතුර තවත් වැඩි දියුණු කිරීම සඳහා මම කරුණු දෙකක් කරන්නෙමි: 1: ජොෂ්ගේ පිළිතුර මෙන් එය සරල කිරීමට "&>" භාවිතා කරන්න. 2:
read

යමෙකුට අවශ්‍ය නම් මම මෙම ලයිනර් එක බාෂ් ශ්‍රිතයකට දැමුවෙමි
සමාන

94

මගේ .bashrc හි අර්ථ දක්වා ඇති ශ්‍රිතයක් මා සතුව ඇති අතර මෙය පහසු කරයි.

command_exists () {
    type "$1" &> /dev/null ;
}

මෙන්න එය භාවිතා කරන ආකාරය පිළිබඳ උදාහරණයක් (මගේ සිට .bash_profile)

if command_exists mvim ; then
    export VISUAL="mvim --nofork"
fi

මොකක්ද මේ කරන්නේ &>ද?
සාද් මලික්


&>ඔබගේ බාෂ් අනුවාදයේ නොතිබිය හැකිය. මාසෙලෝගේ කේතය හොඳින් ක්‍රියාත්මක විය යුතුය; එය එකම දේ කරයි.
ජොෂ් ස්ට්‍රේටර්

3
බිල්ඩින් සහ වෙන් කළ වචන අසමත් වේ: thenඋදාහරණයක් ලෙස වචනය සමඟ මෙය උත්සාහ කරන්න . ක්‍රියාත්මක කළ හැකි දේ පැවතිය යුතු නම් මෙම පිළිතුර බලන්න $PATH.
ටොම් හේල්

84

එය රඳා පවතින්නේ $PATHවිචල්‍යයේ එක් නාමාවලියක එය පවතින්නේද යන්න හෝ එහි නිරපේක්ෂ පිහිටීම ඔබ දන්නේද යන්න මතය. එය $PATHවිචල්යයේ තිබේදැයි දැන ගැනීමට අවශ්ය නම් , භාවිතා කරන්න

if which programname >/dev/null; then
    echo exists
else
    echo does not exist
fi

වෙනත් ආකාරයකින් භාවිතා කරන්න

if [ -x /path/to/programname ]; then
    echo exists
else
    echo does not exist
fi

/dev/null/පළමු උදාහරණය වෙත හරවා යැවීම whichවැඩසටහනේ ප්‍රතිදානය යටපත් කරයි .


22
මගේ අදහස් දැක්වීමේ දක්වා ඇති හේතු සඳහා ඔබ ඇත්ත වශයෙන්ම "කුමන" භාවිතා නොකළ යුතුය.
lhunath

39

H ලුනාත්ගේ සහ @ ග්‍රෙග්වීගේ පිළිතුරු පුළුල් කරමින්, එම චෙක්පත පහසුවෙන් ifප්‍රකාශයක් තුළට දැමීමට අවශ්‍ය පුද්ගලයින් සඳහා වන කේතය මෙන්න :

exists()
{
  command -v "$1" >/dev/null 2>&1
}

එය භාවිතා කරන ආකාරය මෙන්න:

if exists bash; then
  echo 'Bash exists!'
else
  echo 'Your system does not have Bash'
fi

13
ඉගෙනීමට හා වැඩිදියුණු කිරීමට ඇති කැමැත්ත විපාක ලැබිය යුතුය. +1 මෙය පිරිසිදු හා සරල ය. මට එකතු කළ හැකි එකම දෙය නම් commandඅන්වර්ථ නාම සඳහා පවා සාර්ථක වීමයි , එය තරමක් ප්‍රතිවිරුද්ධ විය හැකිය. අන්තර්ක්‍රියාකාරී කවචයක පැවැත්ම පරීක්ෂා කිරීම ඔබ එය ස්ක්‍රිප්ටයකට ගෙන යන විට වෙනස් ප්‍රති results ල ලබා දෙනු ඇත.
පලෙක්

1
මම shopt -u expand_aliasesනොසලකා හැර / සැඟවුණු අන්වර්ථයන් ( alias ls='ls -F'වෙනත් පිළිතුරක සඳහන් කර ඇති පරිදි) පරීක්ෂා කර ඒවා shopt -s expand_aliasesවිසඳා ගනිමි command -v. එබැවින් සමහර විට එය චෙක්පතට පෙර සකසා පසුව සැකසිය යුතුය, නමුත් ඔබ විධාන ඇමතුමේ ප්‍රතිදානය පැහැදිළිව ආපසු ලබා නොදුනහොත් එය ක්‍රියාකාරී ප්‍රතිලාභ අගයට බලපායි.
dragon788

24

භාවිතා කිරීමට උත්සාහ කරන්න:

test -x filename

හෝ

[ -x filename ]

කොන්දේසි සහිත ප්‍රකාශන යටතේ ඇති Bash manpage වෙතින් :

 -x file
          True if file exists and is executable.

26
ඒ කියන්නේ ඔබ දැනටමත් යෙදුමේ සම්පූර්ණ මාර්ගය දැන සිටිය යුතුයි.
ලූනාත්

12
ඔහුට නිශ්චිත අවස්ථාවක් හෝ ක්‍රියාත්මක කළ හැකි නිදසුනක් පරීක්ෂා කිරීමට අවශ්‍ය දැයි OP නිශ්චිතව දක්වා නැත ... මම එය කියවූ ආකාරයටම පිළිතුරු දුනිමි.
dmckee --- හිටපු උපපරිපාලක පූස් පැටවා

16

භාවිතා කිරීම hash, @lhunath ලෙස යෝජනා වූ බෑෂ් කේත රචනය තුල,:

hash foo &> /dev/null
if [ $? -eq 1 ]; then
    echo >&2 "foo not found."
fi

මෙම ස්ක්‍රිප්ට් එක ක්‍රියාත්මක hashවන අතර නවතම විධානයෙහි පිටවීමේ කේතය, ගබඩා කර ඇති අගය $?සමාන දැයි පරීක්ෂා 1කරයි. නම් hashසොයා නැත foo, පිටවීම කේතය වනු ඇත 1. තිබේ නම් foo, පිටවීමේ කේතය වනු ඇත 0.

&> /dev/nullයළි-යොමුවීම් සම්මත දෝෂයක් හා සම්මත ප්රතිදානය සිට hashඑය තිරය මත දිස් හා නොවන බව echo >&2සම්මත දෝෂයක් පණිවිඩය මෙසේ ලියයි.


9
ඇයි නැත්තේ if hash foo &> /dev/null; then ...?
බෙනී චර්නියාව්ස්කි-පැස්කින්

9

මට පිවිසිය හැකි කොටුවේ වැඩ කිරීමට පෙර පිළිතුරු මට ලැබුනේ නැත. එකක් සඳහා, typeස්ථාපනය කර ඇත (කරන දේ moreකිරීම). එබැවින් බිල්ඩින් නියෝගය අවශ්‍ය වේ. මෙම විධානය මට වැඩ කරයි:

if [ `builtin type -p vim` ]; then echo "TRUE"; else echo "FALSE"; fi

4
වරහන් ifසින්ටැක්ස් වල කොටසක් නොවේ , සරලව භාවිතා කරන්න if builtin type -p vim; then .... හා backticks ඇත්තටම පැරණි සාපේක්ෂව කාරක රීති වන අතර, $()අය විසින් පවා, සහාය shනවීන පද්ධති මත.
nyuszika7h

9

බහුවිධ පරායත්තතාවයන් පරීක්ෂා කර අවසන් පරිශීලකයින්ට තත්වය දැනුම් දෙන්න

for cmd in latex pandoc; do
  printf '%-10s' "$cmd"
  if hash "$cmd" 2>/dev/null; then
    echo OK
  else
    echo missing
  fi
done

නියැදි ප්‍රතිදානය:

latex     OK
pandoc    missing

හැඩ 10උපරිම විධානය දිග. එය ස්වයංක්‍රීය නොවේ, මන්ද එය කිරීමට වාචික නොවන POSIX ක්‍රමයක් මා දකින්නේ නැත: Bash හි අවකාශය වෙන් කළ වගුවක තීරු පෙළගස්වන්නේ කෙසේද?

සමහර aptපැකේජ සමඟ ස්ථාපනය කර ඇත්දැයි පරීක්ෂා dpkg -sකර වෙනත් ආකාරයකින් ස්ථාපනය කරන්න .

බලන්න: apt-get පැකේජයක් ස්ථාපනය කර ඇත්දැයි පරීක්ෂා කර එය ලිනක්ස් හි නොමැති නම් එය ස්ථාපනය කරන්න

එය කලින් සඳහන් කර තිබුණේ: Bash ස්ක්‍රිප්ට් එකකින් වැඩසටහනක් තිබේදැයි පරීක්ෂා කරන්නේ කෙසේද?


1
එය කිරීමට වාචික නොවන ක්‍රමය: 1) පළල පිරිවිතරයෙන් ඉවත් වන්න; 2) ඔබේ විධාන නාමයේ මුද්‍රණයෙන් පසු ඉඩක් එක් කරන්න; 3) ඔබේ ලූපය සඳහා පයිප්ප නල කරන්න column -t(util-linux හි කොටසක්).
පැට්‍රිස් ලෙවෙස්ක්

8

ඔබ වැඩසටහන් පැවැත්ම පරීක්ෂා කරන්නේ නම්, ඔබ එය කෙසේ හෝ පසුව ක්‍රියාත්මක කිරීමට යන්නේ ය. එය මුලින් ක්‍රියාත්මක කිරීමට උත්සාහ නොකරන්නේ ඇයි?

if foo --version >/dev/null 2>&1; then
    echo Found
else
    echo Not found
fi

හුදෙක් PATH නාමාවලි සහ ගොනු අවසරයන් දෙස බැලීමට වඩා වැඩසටහන ක්‍රියාත්මක වන බව වඩා විශ්වාසදායක පරීක්ෂාවකි.

ප්ලස් ඔබට ඔබේ වැඩසටහනෙන් එහි අනුවාදය වැනි ප්‍රයෝජනවත් ප්‍රති result ල ලබා ගත හැකිය.

ඇත්ත වශයෙන්ම අඩුපාඩු වන්නේ සමහර වැඩසටහන් ආරම්භ කිරීමට බර විය හැකි අතර සමහර --versionඒවාට වහාම (සහ සාර්ථකව) පිටවීමට විකල්පයක් නොමැති වීමයි.


6

hash foo 2>/dev/null: Z shell (Zsh), Bash, Dash සහ අළු සමඟ ක්‍රියා කරයි .

type -p foo: එය Z shell, Bash සහ ash ( BusyBox ) සමඟ වැඩ කරන බව පෙනේ , නමුත් Dash නොවේ (එය -pතර්කයක් ලෙස අර්ථ නිරූපණය කරයි).

command -v foo: Z shell, Bash, Dash සමඟ ක්‍රියා කරයි, නමුත් අළු නොවේ (BusyBox) ( -ash: command: not found).

builtinඅළු සහ ඩෑෂ් සමඟ ලබා ගත නොහැකි බව සලකන්න .


5

පරීක්ෂා කිරීම සඳහා -vPOSIX_BUILTINS විකල්පය සකසා ඇත්නම් විධානය හොඳින් ක්‍රියාත්මක වේ, නමුත් එසේ නොවුවහොත් <command>එය අසාර්ථක විය හැකිය. (එය වසර ගණනාවක් තිස්සේ මා වෙනුවෙන් වැඩ කර ඇත, නමුත් මෑතකදී මම එය ක්‍රියාත්මක නොවූ තැනකට දිව ගියෙමි.)

පහත සඳහන් දෑ වඩාත් අසාර්ථක බව මට පෙනේ:

test -x $(which <command>)

එය කරුණු තුනක් සඳහා පරීක්ෂා කරන බැවින්: මාර්ගය, පැවැත්ම සහ ක්‍රියාත්මක කිරීමේ අවසරය.


වැඩ කරන්නේ නැහැ. ස්ථාපනය කර ධාවනය කළ හැකි වුවත්, මා ධාවනය කරන ඩොකර් බහාලුම තුළ පවා ස්ථාපනය කර නොමැති වුවද test -x $(which ls), 0 ආපසු එයි .test -x $(which sudo)lssudo
ඇල්ගල්

alalgal ඔබ මා සිතන උපුටා දැක්වීම් භාවිතා කළ යුතුය, එබැවින්test -x "$(which <command>)"
JoniVR

ඇල්ගල් සමහර විට අන්වර්ථ lsවී තිබේද? විධානයට පරාමිතියක් තිබේ නම් එය ක්‍රියාත්මක වනු ඇතැයි මම නොසිතමි.
ඇන්තනි සී

4

ඔබට හැකි නම් Bash buildins භාවිතා කරන්න:

which programname

...

type -P programname

15
හහ්? whichබෑෂ් බිල්ඩින් නොවේ.
ත්‍රිත්ව


O රොබට් ජී මා දකින සියල්ල එය පොසික්ස් -Pනොවේ. ඇයි ඇත type -Pකැමති?
mikemaccana

මා විසින් වාක්‍ය ඛණ්ඩනය කළ යුතුව තිබුණේ "බාෂ් පරිසරය තුළ වඩාත් කැමති වීමට" - මා අදහස් කළේ විශේෂිත වූ පෙර අදහස් දැක්වීමට පිළිතුරු දීමට ය. කෙසේ හෝ වේවා, එය මීට වසර ගණනාවකට පෙර විය - මම අනුමාන කරන්නේ, නැවත වරක්, “අනුබල දුන්” ලෙස සලකුණු කර ඇති පිළිතුර වෙත යොමු කළ යුතු බවයි
රොබට් ජී

4

මෙහි විකල්ප ටොන් ගණනක් ඇත, නමුත් ඉක්මන් එක් ලයිනර් නොමැති වීම ගැන මම පුදුමයට පත් වීමි. මගේ පිටපත් ආරම්භයේ දී මා භාවිතා කළේ මෙයයි:

[[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1>&2 ; exit 1; }
[[ "$(command -v java)" ]] || { echo "java is not installed" 1>&2 ; exit 1; }

මෙය පදනම් වී ඇත්තේ මෙහි තෝරාගත් පිළිතුර සහ තවත් ප්‍රභවයක් මත ය.


3

උනන්දුවක් දක්වන අය සඳහා, ඔබ විසින් ස්ථාපනය කරන ලද පුස්තකාලයක් හඳුනා ගැනීමට අවශ්‍ය නම් පෙර පිළිතුරු වල කිසිදු ක්‍රමවේදයක් ක්‍රියාත්මක නොවේ. මා සිතන්නේ ඔබට මාර්ගය භෞතිකව පරික්ෂා කිරීම (ශීර්ෂ ලිපිගොනු සහ එවැනි දේ සඳහා විය හැකිය) හෝ මේ වගේ දෙයක් (ඔබ ඩේබියන් පදනම් කරගත් බෙදාහැරීමක සිටී නම්) ඉතිරි වනු ඇති බවයි:

dpkg --status libdb-dev | grep -q not-installed

if [ $? -eq 0 ]; then
    apt-get install libdb-dev
fi

ඉහත සිට ඔබට පෙනෙන පරිදි, විමසුමේ "0" පිළිතුරෙන් අදහස් වන්නේ පැකේජය ස්ථාපනය කර නොමැති බවයි. මෙය "grep" හි ශ්‍රිතයකි - "0" යන්නෙන් අදහස් වන්නේ ගැලපීමක් හමු වූ බවයි, "1" යන්නෙන් අදහස් කරන්නේ කිසිදු ගැලපීමක් හමු නොවීමයි.


10
කෙසේ වෙතත්, ප්‍රති-රටාව cmd; if [ $? -eq 0 ]; thenනැවත සකස් කළ යුතුයif cmd; then
ත්‍රිත්ව

මෙය ක්‍රියාත්මක වන්නේ dpkgහෝapt
වයිජුන් ෂෝ

2

මම කියන්නේ එල්ලා වැටෙන නිසා අතේ ගෙන යා හැකි සහ 100% විශ්වාසදායක ක්‍රමයක් නොමැති බවයි alias. උදාහරණයක් වශයෙන්:

alias john='ls --color'
alias paul='george -F'
alias george='ls -h'
alias ringo=/

ඇත්ත වශයෙන්ම, අවසාන එක පමණක් ගැටළු සහගතය (රින්ගෝට වරදක් නැත!). නමුත් ඒවා සියල්ලම වලංගු aliasවේ command -v.

වැනි අන්තරාදායක ඒවා ප්‍රතික්ෂේප කිරීම සඳහා ringo, අපි ෂෙල් බිල්ට්- aliasවිධාන ප්‍රතිදානය විග්‍රහ කොට ඒවාට නැවත යොමු විය යුතුය ( මෙහි command -vවඩා උසස් නොවේ alias.) ඒ සඳහා අතේ ගෙන යා හැකි විසඳුමක් නොමැත, සහ බාෂ්- නිශ්චිත විසඳුම තරමක් වෙහෙසකරය.

මෙවැනි විසඳුමක් කොන්දේසි විරහිතව ප්‍රතික්ෂේප කරන බව සලකන්න alias ls='ls -F':

test() { command -v $1 | grep -qv alias }

හොඳ කරුණක්. කෙසේ වෙතත්, බෑෂ් ස්ක්‍රිප්ටයක් තුළ සිට ධාවනය වන විට අන්වර්ථයන් නොපෙනේ.
බැසිල් මූසා

1
ගැටළුවක් ද ඇත, 'අන්වර්ථය' විධානය පරීක්ෂා කළ විට එය අසත්‍ය වේ. එය සත්‍ය විය යුතු විට. උදාහරණය: "අන්වර්ථය" පරීක්ෂා කරන්න
බැසිල් මූසා

2
මම shopt -u expand_aliasesමේ අන්වර්ථයන් නොසලකා හැර / සඟවා shopt -s expand_aliasesඒවා හරහා පෙන්වමි command -v.
dragon788

2

වැඩසටහන තිබේද නැද්ද යන්න මෙය ස්ථානය අනුව කියනු ඇත:

    if [ -x /usr/bin/yum ]; then
        echo "This is Centos"
    fi

ඔව්, මම මෙම විධානය එකතු කළේ ඔබට සෙවරර්, ඕපන් සූස්, සෙන්ටෝස්, ඩේබියන්
ක්ලෙවින් කෝනා

සින්ටැක්ස් ඉස්මතු කිරීම "echo" රේඛාවේ අක්‍රිය කර ඇත. විසඳුම කුමක්ද? Bash ස්ක්‍රිප්ට් වෙනස් විය යුතු යැයි එයින් යෝජනා වේද?
පීටර් මෝර්ටෙන්සන්

EtPeterMortensen සින්ටැක්ස් ඉස්මතු කිරීම අක්‍රිය කර ඇත්තේ එය නූල් හඳුනා නොගන්නා බැවිනි.
ඇඩ්‍රියන්

1

ඩේබියන් සේවාදායකයක් සඳහා මගේ සැකසුම :

බහුවිධ පැකේජවල එකම නමක් අඩංගු වූ විට මට ගැටලුව ඇති විය.

උදාහරණයක් ලෙස apache2. එබැවින් මෙය මගේ විසඳුම විය:

function _apt_install() {
    apt-get install -y $1 > /dev/null
}

function _apt_install_norecommends() {
    apt-get install -y --no-install-recommends $1 > /dev/null
}
function _apt_available() {
    if [ `apt-cache search $1 | grep -o "$1" | uniq | wc -l` = "1" ]; then
        echo "Package is available : $1"
        PACKAGE_INSTALL="1"
    else
        echo "Package $1 is NOT available for install"
        echo  "We can not continue without this package..."
        echo  "Exitting now.."
        exit 0
    fi
}
function _package_install {
    _apt_available $1
    if [ "${PACKAGE_INSTALL}" = "1" ]; then
        if [ "$(dpkg-query -l $1 | tail -n1 | cut -c1-2)" = "ii" ]; then
             echo  "package is already_installed: $1"
        else
            echo  "installing package : $1, please wait.."
            _apt_install $1
            sleep 0.5
        fi
    fi
}

function _package_install_no_recommends {
    _apt_available $1
    if [ "${PACKAGE_INSTALL}" = "1" ]; then
        if [ "$(dpkg-query -l $1 | tail -n1 | cut -c1-2)" = "ii" ]; then
             echo  "package is already_installed: $1"
        else
            echo  "installing package : $1, please wait.."
            _apt_install_norecommends $1
            sleep 0.5
        fi
    fi
}

1

ඔබට / ගැල්වරුන්ට මෙහි වැඩ කිරීමට පිළිතුරු ලබා ගත නොහැකි නම් සහ ඔබේ පිටුපසට කොණ්ඩය අදින්නේ නම්, එකම විධානය භාවිතා කර ක්‍රියාත්මක කිරීමට උත්සාහ කරන්න bash -c. මේ සොබාදහමේ ව්‍යාකූලත්වය දෙස බලන්න. ඔබ run (උප විධානය) ධාවනය කරන විට සැබවින්ම සිදුවන්නේ මෙයයි:

පලමු. එය ඔබට සම්පූර්ණයෙන්ම වෙනස් ප්‍රතිදානයක් ලබා දිය හැකිය.

$ command -v ls
alias ls='ls --color=auto'
$ bash -c "command -v ls"
/bin/ls

දෙවැනි. එය ඔබට කිසිසේත්ම ප්‍රතිදානයක් ලබා දිය නොහැක.

$ command -v nvm
nvm
$ bash -c "command -v nvm"
$ bash -c "nvm --help"
bash: nvm: command not found

කවචයේ අන්තර්ක්‍රියාකාරී හා අන්තර්ක්‍රියාකාරී නොවන මාදිලිය අතර වෙනස නිසා වෙනස්කම් ඇතිවේ. ඔබේ ~ / .bashrc කියවනු ලබන්නේ කවචය පුරනය නොවූ සහ අන්තර්ක්‍රියාකාරී වූ විට පමණි. දෙවැන්න අමුතු බවක් පෙනුනද, මෙය සිදුවිය යුත්තේ PATH පරිසර විචල්‍යයේ වෙනසක් නිසා විය යුතුය, නමුත් අනුකාරක මගින් පරිසරය උරුම වේ.
පලෙක්

මගේ නඩුවේදී .bashrcපෙර [ -z "$PS1" ] && returnසූදානමක් ඇති # If not running interactively, don't do anythingබැවින් අන්තර්ක්‍රියාකාරී නොවන ආකාරයෙන් පැහැදිලි ලෙස බාෂ්ර්ක් ලබා ගැනීම පවා උදව් නොකිරීමට එය හේතුවක් යැයි මම සිතමි. Ss64.com/bash/source.html තිත් ක්‍රියාකරු සමඟ ස්ක්‍රිප්ට් එකක් ඇමතීමෙන් ගැටළුව විසඳා ගත හැකි . ./script.shනමුත් එය එක් එක් වර ටයිප් කිරීමට මතක තබා ගැනීමට කැමති දෙයක් නොවේ.
user619271

1
උපුටා ගත යුතු නොවන මූලාශ්‍ර පිටපත් කිරීම නරක අදහසකි. මම කියන්නට උත්සාහ කළේ ඔබේ පිළිතුර අසන ලද ප්‍රශ්නයට එතරම් සම්බන්ධයක් නැති අතර බාෂ් සහ එහි (නොවන) අන්තර්ක්‍රියාකාරී මාදිලිය සමඟ බොහෝ දේ කළ හැකි බවයි.
පලෙක්

මෙම අවස්ථා වලදී සිදුවන්නේ කුමක්ද යන්න එය පැහැදිලි කළේ නම්, එය පිළිතුරකට උපකාරී වන අතිරේකයක් වනු ඇත.
පලෙක්

0

හැෂ්-ප්‍රභේදයට එක් අනතුරක් ඇත: විධාන රේඛාවේදී ඔබට උදාහරණයක් ලෙස ටයිප් කළ හැකිය

one_folder/process

ක්‍රියාවලිය ක්‍රියාත්මක කිරීමට. මේ සඳහා one_folder හි මව් ෆෝල්ඩරය $ PATH හි තිබිය යුතුය . නමුත් ඔබ මෙම විධානය හැෂ් කිරීමට උත්සාහ කරන විට, එය සැමවිටම සාර්ථක වනු ඇත:

hash one_folder/process; echo $? # will always output '0'

4
"මේ සඳහා one_folder හි මව් ෆෝල්ඩරය තිබිය යුතුය $PATH" - මෙය සම්පූර්ණයෙන්ම සාවද්‍ය ය. උත්සහ කරන්න. මෙය ක්‍රියාත්මක වීමට නම්, එක්_ ෆෝල්ඩරයක් වත්මන් නාමාවලියෙහි තිබිය යුතුය .
වයිල්ඩ්කාඩ්

0

මම දෙවනුව "විධානය -v" භාවිතා කරමි. උදා: මේ වගේ:

md=$(command -v mkdirhier) ; alias md=${md:=mkdir}  # bash

emacs="$(command -v emacs) -nw" || emacs=nano
alias e=$emacs
[[ -z $(command -v jed) ]] && alias jed=$emacs

0

මෙම whichවිධානය ප්රයෝජනවත් විය හැකිය. මිනිසා

ක්‍රියාත්මක කළ හැකි දේ සොයාගත හොත් එය 0 ලබා දෙන අතර එය සොයාගත නොහැකි නම් හෝ ක්‍රියාත්මක කළ නොහැකි නම් 1 ලබා දෙයි:

NAME

       which - locate a command

SYNOPSIS

       which [-a] filename ...

DESCRIPTION

       which returns the pathnames of the files which would
       be executed in the current environment, had its
       arguments been given as commands in a strictly
       POSIX-conformant shell. It does this by searching
       the PATH for executable files matching the names
       of the arguments.

OPTIONS

       -a     print all matching pathnames of each argument

EXIT STATUS

       0      if all specified commands are 
              found and executable

       1      if one or more specified commands is nonexistent
              or not executable

       2      if an invalid option is specified

මෙහි ඇති හොඳ දෙය whichනම්, ක්‍රියාත්මක කළ හැකි පරිසරය තුළ ක්‍රියාත්මක කළ හැකි දැයි සොයා ගැනීමයි which- එය ගැටළු කිහිපයක් ඉතිරි කරයි ...


ඔබ විසින් ක්‍රියාත්මක කළ හැකි foo නම් යමක් සොයන්නේ නම් එය භාවිතා කරන්න, නමුත් ඔබට විශේෂිත ගොනුවක් / මාර්ගයක් / / / / / නම් / foo පරීක්ෂා කිරීමට අවශ්‍ය නම් මගේ පිළිතුර බලන්න. සමහර අවම පද්ධතිවල නොතිබිය හැකි බව සලකන්න, එය ඕනෑම අංග සම්පූර්ණ ස්ථාපනයක තිබිය යුතුය ...
dmckee --- හිටපු උපපරිපාලක පූස් පැටවා

9
එහි පිටවීමේ තත්වය මත රඳා නොසිටින්න. බොහෝ මෙහෙයුම් පද්ධති වල 0 හැර වෙනත් පිටවීමේ තත්වයක් පවා සකසා නැති
lhunath

0

අපගේ CI සේවාදායකය යෙදවීමේ කොටසක් ලෙස Git ස්ථාපනය කර ඇත්දැයි පරීක්ෂා කිරීමට මට සිදු විය . මගේ අවසාන බෑෂ් පිටපත පහත පරිදි විය (උබුන්ටු සේවාදායකය):

if ! builtin type -p git &>/dev/null; then
  sudo apt-get -y install git-core
fi

3
කොන්දේසිය තරමක් නිෂ් less ල ය, apt-get ධාවනය කිරීමට ආරම්භක වේලාව මොඩියුලය කරන්න, apt-get සෑහීමකට පත්වන අතර git-core දැනටමත් ස්ථාපනය කර ඇත්නම් පිටවීම.
ත්‍රිත්ව

4
එහි ආරම්භක වේලාව නොසැලකිලිමත් නොවන නමුත් වඩා වැදගත් අභිප්‍රේරණය වන්නේ sudo: කොන්දේසි විරහිතව, එය සැමවිටම නතර වී මුරපදය ඉල්ලනු ඇත (ඔබ මෑතකදී සුඩෝවක් නොකළේ නම්). BTW, එසේ කිරීම ප්‍රයෝජනවත් විය හැකි sudo -p "Type your password to install missing git-core: "බැවින් විමසුම නිල් පාටින් නොපැමිණේ.
බෙනී චර්නියාව්ස්කි-පැස්කින්

0

Bash හි අනුකරණය කිරීමට type -P cmd, අපට POSIX අනුකූලතාවය භාවිතා කළ හැකිය env -i type cmd 1>/dev/null 2>&1.

man env
# "The option '-i' causes env to completely ignore the environment it inherits."
# In other words, there are no aliases or functions to be looked up by the type command.

ls() { echo 'Hello, world!'; }

ls
type ls
env -i type ls

cmd=ls
cmd=lsx
env -i type $cmd 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }

7
මෙය ඉහළට ඔසවා තබන්නේ ඇයි? මෙය ඇත්ත වශයෙන්ම ඔබ වෙනුවෙන් ක්‍රියාත්මක වන්නේ කුමන පද්ධති මතද? බොහෝ ෂෙල් වෙඩි වල ඇති typeබව පෙනේ, builtinඑබැවින් මෙය ක්‍රියාත්මක කළ නොහැකි බැවින් ධාවනය envසඳහා භාවිතා execvpකිරීම commandඑසේ commandවිය නොහැක builtin(සහ builtinසෑම විටම එකම පරිසරය තුළ ක්‍රියාත්මක වේ). මේ මට අසමත් bash, ksh93, zsh, busybox [a]shහා dashවන සියලු ලබා typeතිබෙන shell builtin ලෙස.
ඒඩ්‍රියන් ෆ්‍රොවර්ත්

0

බාහිර typeවිධානයක් නොමැති නම් ( මෙහි දක්වා ඇති පරිදි ), අපට POSIX අනුකූලතාවය භාවිතා කළ හැකිය env -i sh -c 'type cmd 1>/dev/null 2>&1':

# Portable version of Bash's type -P cmd (without output on stdout)
typep() {
   command -p env -i PATH="$PATH" sh -c '
      export LC_ALL=C LANG=C
      cmd="$1"
      cmd="`type "$cmd" 2>/dev/null || { echo "error: command $cmd not found; exiting ..." 1>&2; exit 1; }`"
      [ $? != 0 ] && exit 1
      case "$cmd" in
        *\ /*) exit 0;;
            *) printf "%s\n" "error: $cmd" 1>&2; exit 1;;
      esac
   ' _ "$1" || exit 1
}

# Get your standard $PATH value
#PATH="$(command -p getconf PATH)"
typep ls
typep builtin
typep ls-temp

අවම වශයෙන් මැක් ඕඑස් එක්ස් v10.6.8 (හිම දිවියා) මත බාෂ් 4.2.24 (2) භාවිතා කිරීම චලනයකට command -v lsනොගැලපේ /bin/ls-temp.


0

ඔබට යම් වැඩසටහනක් තිබේද යන්න පරීක්ෂා කර බැලීමට අවශ්‍ය නම් එය සැබවින්ම වැඩසටහනක් මිස බාෂ් බිල්ට් විධාන නොවේ නම් command, typeසහhash ඔවුන් බිල්ට් විධාන සඳහා සියලු ආපසු 0 පිටවීමේ තත්ත්වය පරීක්ෂා කිරීම සඳහා සුදුසු නොවේ.

උදාහරණයක් ලෙස, පවතින කාලය වඩා වැඩි විශේෂාංග පිරිනමන වැඩසටහන කාලය බිල්ට් විධාන. වැඩසටහන තිබේද යන්න පරීක්ෂා කිරීම whichසඳහා, පහත දැක්වෙන උදාහරණයේ දී මෙන් භාවිතා කිරීමට මම යෝජනා කරමි :

# First check if the time program exists
timeProg=`which time`
if [ "$timeProg" = "" ]
then
  echo "The time program does not exist on this system."
  exit 1
fi

# Invoke the time program
$timeProg --quiet -o result.txt -f "%S %U + p" du -sk ~
echo "Total CPU time: `dc -f result.txt` seconds"
rm result.txt

0

මට අවශ්‍ය වූයේ එකම ප්‍රශ්නයට පිළිතුරු දීමට මිස මේක්ෆයිල් එකක් තුළ ක්‍රියාත්මක වීමටය.

install:
    @if [[ ! -x "$(shell command -v ghead)" ]]; then \
        echo 'ghead does not exist. Please install it.'; \
        exit -1; \
    fi

0

එය වඩාත් සරල විය හැකිය:

#!/usr/bin/env bash                                                                
set -x                                                                             

# if local program 'foo' returns 1 (doesn't exist) then...                                                                               
if ! type -P foo; then                                                             
    echo 'crap, no foo'                                                            
else                                                                               
    echo 'sweet, we have foo!'                                                    
fi                                                                                 

වෙනස් fooකිරීමට viගිනි අනෙක් තත්ත්වය ලබා ගැනීමට.


-1

පිටපත

#!/bin/bash

# Commands found in the hash table are checked for existence before being
# executed and non-existence forces a normal PATH search.
shopt -s checkhash

function exists() {
 local mycomm=$1; shift || return 1

 hash $mycomm 2>/dev/null || \
 printf "\xe2\x9c\x98 [ABRT]: $mycomm: command does not exist\n"; return 1;
}
readonly -f exists

exists notacmd
exists bash
hash
bash -c 'printf "Fin.\n"'

ප්‍රති ult ලය

 [ABRT]: notacmd: command does not exist
hits    command
   0    /usr/bin/bash
Fin.
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.