Proqramın baş scriptindən olub olmadığını necə yoxlamaq olar?

Səhv qayıdın və çıxışdan çıxacaq və ya skriptdən istifadə etməyə davam edəcək bir proqramın olub-olmadığını necə kontrol edə bilərəm?

Göründüyü kimi, bu, asan olmalı idi, amma məni yaraladı.

1748
27 февр. 27 feb . 2009-02-27 00:52 '09 at 12:52 AM 2009-02-27 00:52
@ 35 cavab
  • 1
  • 2

Cavab

POSIX uyğunluğu:

 command -v <the_command> 

bash xüsusi mühit üçün:

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

Təsvir

Qaça which . Bu, çox az işləməyiniz üçün çalışan bir xarici proses deyil ( hash , type və ya command kimi funksiyaları daha ucuzdur), həqiqətən istədiyiniz şeyi yerinə yetirmək üçün quraşdırılmış funksiyalara da istinad edə bilərsiniz. Xarici əmrlərin təsiri sistemdən sistemə asanlıqla dəyişə bilər.

Niyə qayğı?

  • Bir çox əməliyyat sistemi, hətta çıxış statüsünü təyin etmir , yəni if which foo hətta orada if which foohəmişə bu foo var, hətta olmadıqda (bəzi POSIX kabuklarının da göründüyü kimi) bu hash üçün).
  • Bir çox əməliyyat sistemi, məhsulun dəyişdirilməsi və ya paket menecerinə qoşulması kimi sadə və pisdir.

Yəni istifadə etməyin. Bunun əvəzinə bunlardan birini istifadə edin:

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

(Qeydin kiçik tərəfi: bəziləri 2>> eyni 2>/dev/null , lakin daha az səhvdir 2>> FD 2-i bağlayır, bu yazıdan müvəffəqiyyətlə yazmaq və çıxışı (və təhlükəli!) çox fərqli olan)

Sizin hash tracks /bin/sh , onda siz POSIX deyir nə qayğı olmalıdır. typehash çıxış kodları POSIX tərəfindən yaxşı müəyyən edilmir və görürsünüz ki, komanda mövcud olmadıqda (hələ bu type ilə görməmişəm) uğurla tamamlanır. command çıxışı statusu POSIX tərəfindən yaxşı müəyyən edilir, buna görə istifadə etmək ən təhlükəsizdir.

Ssenariniz bash istifadə edirsə, POSIX qaydaları artıq əhəmiyyətsizdir və hər iki typehash istifadə etmək üçün tamamilə təhlükəsiz olur. type yalnız PATH axtarış etmək üçün -P malikdir və hash əmrinin yerləşdiyi yerin (bir dəfə istifadə etdiyiniz zaman daha sürətli axtarış üçün) yerləşdiriləcəyini yanlış təsirə malikdir, bu da adətən yaxşıdır, çünki ehtimal ki, həqiqətən istifadə edin.

Sadə bir nümunə olaraq, burada varsa gdate işləyən funksiyadır, əks halda date :

 gnudate() { if hash gdate 2>/dev/null; then gdate "$@" else date "$@" fi } 
2478
24 марта '09 в 15:45 2009-03-24 15:45 Cavab lunat tərəfindən 24 mart 2009- cu il saat 15: 45-də verilir. 2009-03-24 15:45

Aşağıdakı bir əmri $PATH mövcud olub-olmadığını yoxlamaq üçün portativ bir üsuldur:

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

Məsələn:

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

Check $PATH bu adla yürütülebilir bir fayl olmadığı təqdirdə bash qeyri-yürütülebilir fayl qaytarır, çünki tələb olunur.

Qeyd edək ki, əvvəlki $PATH ilə eyni faylda istifadə olunan faylın adı ilə istifadə olunmamış bir fayl varsa, ikincisi icra edilsə də, dash ilkini qaytarır. Bu səhv POSIX standartına zidd deyil. [ Error Report ] [ Standard ]

Bundan əlavə, aradığınız komanda ləqəbi kimi müəyyən edildikdə bu müvəffəqiyyətsiz olacaq.

324
05 нояб. cavab nyuszika7h 05 noyabr. 2014-11-05 17:33 '14 at 17:33 2014-11-05 17:33

Mən istifadə etməkdən imtina etmək üçün lunat ilə razıyam və onun həlli BASH istifadəçiləri üçün böyükdür. Lakin, daha portativ olmaq üçün, əvəzinə command -v istifadə etməlisiniz:

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

command POSIX ilə uyğun gəlir, onun xüsusiyyətləri baxın : http://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html

Qeyd: type POSIX ilə uyğun gəlir, amma type -P deyil.

194
24 янв. Cavab 24 yanvar GregV tərəfindən verilir 2011-01-24 21:16 '11 at 21:16 2011-01-24 21:16

Mənim .bashrc-da müəyyənləşdirilmiş bir funksiyanı daha asan edir.

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

Burada istifadə olunan bir nümunədir (mənim .bash_profile .)

 if command_exists mvim ; then export VISUAL="mvim --nofork" fi 
83
14 окт. Josh Strater tərəfindən verilmiş cavab 14 oktyabr 2010-10-14 12:24 '10 at 12:24 2010-10-14 12:24

Bu, $PATH dəyişənindəki $PATH birində və ya onun mütləq yerini bildiyinizi bilmək istəməyinizə bağlıdır. $PATH dəyişənində olub olmadığını bilmək istəyirsinizsə, istifadə edin

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

əks halda istifadə edin

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

İlk nümunədə /dev/null/ which proqramın çıxışını basdırır.

68
27 февр. Cavab 27 fevralda yuxu tərəfindən verilir . 2009-02-27 01:01 '09 at 1:01 2009-02-27 01:01

@Lhunath və @GregV cavablarını açarkən, burada if deyiminin içərisində bu çekəni asanlıqla yerinə yetirmək istəyənlər üçün kod:

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

Bunu necə istifadə etmək olar:

 if exists bash; then echo 'Bash exists!' else echo 'Your system does not have Bash' fi 
30
08 дек. Romario tərəfindən verilmiş cavab 08 dekabr. 2015-12-08 00:17 '15 at 0:17 2015-12-08 00:17

Istifadə edin:

 test -x filename 

və ya

 [ -x filename ] 

Bash man page şərti ifadələr :

  -x file True if file exists and is executable. 
20
27 февр. cavab 27 fevralda verilir 2009-02-27 00:57 '09 da 0:57 2009-02-27 00:57

@ Lhunath kimi , hash istifadə etmək üçün, bas skriptində:

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

Bu skript hash çalışır və sonra ən son əmri exit kodu $? saxlanılan dəyəri olub-olmadığını yoxlayır $? 1 bərabərdir. hash foo , çıxış kodu foo . foo varsa, çıxış kodu 0 dir.

/dev/null standart xətanı və standart çıxışı hash ekranda görünməyəcək şəkildə istiqamətləndirir və mesajı echo >> standart xətaya yazır və echo >> yazır.

15
24 июня '11 в 20:01 2011-06-24 20:01 cavab 24 iyun 2011-ci il saat 20: 00 -da verilir

Mənə çatdığım qutu ilə işləmək üçün yuxarıda göstərilən həlləri heç vaxt qəbul etməmişəm. Məsələn, növü müəyyən edilib (daha çox). Buna görə daxili bir direktiv tələb olunur. Bu komanda mənim üçün çalışır:

 if [ `builtin type -p vim` ]; then echo "TRUE"; else echo "FALSE"; fi 
8
11 июля '09 в 21:38 2009-07-11 21:38 Cavab Magnus tərəfindən 11 İyul tarixində saat 21:38 'də verildi. 2009-07-11 21:38

Son istifadəçilərə çoxlu bağımlılıkları və hesabat statüsünü yoxlayın.

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

Nümunə çıxışı:

 latex OK pandoc missing 

10 maksimum komanda uzunluğunu seçin. Avtomatik deyil, çünki POSIX-ın qeyri-tələffüz üsulunu görmürəm: Baş bölgədəki boşluqlu sütunun sütunlarını necə düzəltmək olar?

7
23 марта '14 в 13:09 2014-03-23 13:09 Ciro Santilli tərəfindən verilmiş cavab 改造 改造 中心 六四 事件 Tövsiyə 23 mart '14 də 13:09 2014-03-23 ​​13:09

Bir proqramın mövcudluğunu yoxlayırsan, ehtimal ki, daha sonra başlasın. Niyə ilk cəhd etməliyəm?

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

Bu, proqramın işləyən daha etibarlı bir yoxlama və yalnız PATH qovluqları və fayl icazələrini nəzərdən keçirmək deyil.

Bundan əlavə, proqramınızdan, məsələn, versiyasından faydalı bir nəticə əldə edə bilərsiniz.

Əlbəttə ki, çatışmazlıqlar bəzi proqramların çalışması çətin ola bilər və bəzilərində dərhal (və müvəffəqiyyətli) çıxış üçün variant variantları yoxdur.

7
08 июля '13 в 18:14 2013-07-08 18:14 Cavab 08 İyul 2013 tarixində saat 18: 37 -da verilir

hash foo 2>/dev/null : zsh, bash, tire və kül ilə işləyir.

type -p foo : zsh, bash və kül (busybox) ilə işləyir, ancaq bir dash deyil (bir argümanı şərh edir).

command -v foo : zsh, bash, dash ilə işləyir, lakin kül deyil (busybox) ( -ash: command: not found ).

Həmçinin qeyd edək ki, builtin ashdash ilə mövcud deyil.

6
21 июля '14 в 3:13 2014-07-21 03:13 Cavab, 21 iyul 'da 3:13 2014-07-21 03:13 ' də fırıldaq verilir

Nə üçün daxili Bash xüsusiyyətlərini istifadə edə bilərsiniz?

 which programname 

...

 type -P programname 
6
24 марта '09 в 14:23 2009-03-24 14:23 Cavab 24 mart 2009-cu il tarixində saat 14: 23-də verilir

Maraqlananlar üçün, yuxarıda sadalanan metodologiyaların heç biri quraşdırılmış kitabxananı tapmaq istəyərkən işləyir. Mən güman edirəm ki, yalnız fiziki yolları (başlıq faylları və s. Üçün) və ya bu kimi bir şeyləri yoxlayın (Debian əsaslı bir paylamadan istifadə edirsinizsə):

 dpkg --status libdb-dev | grep -q not-installed if [ $? -eq 0 ]; then apt-get install libdb-dev fi 

Yuxarıdan göründüyü kimi, sorğudan "0" cavabı paketin quraşdırılmadığını bildirir. Bu funksiya "grep" - "0" bir matç deməkdir, "1" isə heç bir matç tapılmadı deməkdir.

4
16 янв. Cavab 16 yanvar Nathan Crause tərəfindən verilir 2010-01-16 02:16 '10 at 2:16 'da 2010-01-16 02:16

which komanda faydalı ola bilər? kimdir

Əldə edilə bilən fayl aşkar edildikdə 0 işarəsi, 1 tapılmadıqda və ya yerinə yetirilmədikdə:

 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 exe- cutable 2 if an invalid option is specified 

Yaxşı şeydir ki, həyata keçirilə bilən fayl mövcud olan mühitdə mövcud olub-olmadığını müəyyən edir - bir neçə problemi saxlayır ...

-Adam

3
27 февр. Cavab 27 fevralda Adam Davis tərəfindən verilir . 2009-02-27 00:56 '09 at 0:56 2009-02-27 00:56

Mən demək olar ki, alias adın asılmasına görə portativ və 100% etibarlı bir yol yoxdur. Məsələn:

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

Əlbəttə ki, sonuncular yalnız problemlidir (Ringo üçün heç bir cinayətdir!) Lakin onların hamısı command -v baxımından etibarlıdır.

ringo kimi çırpılmış bir şeyi rədd etmək üçün, komanda üzərində quraşdırılmış alias adın analizini və kabuka qayıtmasını ( command -v alias keçməməlidir) təhlil etməliyik. Bunun üçün heç bir portativ həlli yoxdur, hətta bash-özəl həll olduqca yorucu.

Xahiş edirik, bu həll şərtini şərtsiz olaraq alias ls='ls -F'

 test() { command -v $1 | grep -qv alias } 
3
10 марта '16 в 5:31 2016-03-10 05:31 Cavab verilir nodakai 10 Mart 'da 5:31 ' də 2016-03-10 05:31

Xarici type komanda mövcud deyilsə ( burada adətən olduğu kimi), POSIX uyğun uyğundur env -i sh -c 'type cmd 1>/dev/null 2>> :

 # portable version of Bash type -P cmd (without output on stdout) typep() { command -p env -i PATH="$PATH" sh -c ' export LC_ALL=C > 

Ən azı Mac OS X 10.6.8-də Bash 4.2.24 (2) command -v ls istifadə edərək, köçürülmüş /bin/ls-temp .

2
20 нояб. Cavab 20 noyabr tarixində fren ilə verilir 2014-11-20 19:55 '14 da 19:55 2014-11-20 19:55

Burada bir çox variant var, amma sürətli tək xəttli simvollar olmadığı zaman mən də təəccüblənməmişdim, bu mənim skriptlərin əvvəlində istifadə etdiyim şeydir: [[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1> exit 1; } [[ "$(command -v java)" ]] || { echo "java is not installed" 1> exit 1; } [[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1> exit 1; } [[ "$(command -v java)" ]] || { echo "java is not installed" 1> exit 1; } [[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1> exit 1; } [[ "$(command -v java)" ]] || { echo "java is not installed" 1> exit 1; } [[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1> exit 1; } [[ "$(command -v java)" ]] || { echo "java is not installed" 1> exit 1; } [[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1> exit 1; } [[ "$(command -v java)" ]] || { echo "java is not installed" 1> exit 1; }

Burada seçilmiş cavab və digər mənbəyə əsaslanır (və bir az oynadım).

Başqaları üçün faydalı olacağına ümid edirəm.

1
19 июня '18 в 15:02 2018-06-19 15:02 Cavay Keisar tərəfindən 19 iyun '18' da 15:02 2018-06-19 15:02 'də verilir

Proqramın mövcudluğunu və həqiqətən proqramı yoxlamaq istəsəniz , bash quraşdırılmış əmr deyil , sonra command , typehash testləri üçün uyğun deyil, çünki onlar bütün daxili əmrlər üçün 0 çıxış statusunu qaytarır.

Məsələn, vaxtın yerindən daha çox xüsusiyyətləri təklif edən bir vaxt proqramı var. Bir proqramın mövcud olub olmadığını yoxlamaq üçün, aşağıdakı nümunədə olduğu kimi, istifadə which görürəm:

 # 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 
1
19 июня '16 в 2:19 2016-06-19 02:19 Cavab 19 İyun 1916 'da 2:19 2016-06-19 02:19 tarixində verilir

İşinizə işləmək və saçınızı arxadan çəkmək üçün yuxarı / aşağı iş ala bilmirsinizsə, bash -c istifadə edərək eyni əmri yerinə yetirməyə çalışın. Yalnız bu şübhəli saçmala baxın, həqiqətən $ (sub-command) işləyərkən belə olur:

Hər şeydən əvvəl. Bu, tamamilə fərqli bir yol ola bilər.

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

İkincisi. Heç bir nəticə vermir.

 $ command -v nvm nvm $ bash -c "command -v nvm" $ bash -c "nvm --help" bash: nvm: command not found 
1
26 авг. 26 avqustda user619271 tərəfindən verilmiş cavab . 2015-08-26 12:23 '15 saat 12:23 'da

debian server üçün quraşdırma. Bir neçə paket eyni adı olan bir problemim var. məsələn apache2. bu mənim qərarım idi.

 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
27 марта '15 в 17:26 2015-03-27 17:26 cavab THCTLo 27 mart '17' də verilir 17:26 2015-03-27 17:26

Hash variantında bir səhv var: əmr satırında, məsələn, daxil olun

 one_folder/process 

prosesi başa çatdırmaq üçün. Bunu etmək üçün, bir qovluqdakı ana qovluq $ PATH olmalıdır. Amma bu əmri həsr etməyə çalışdığınız zaman həmişə uğurlu olacaq:

 hash one_folder/process; echo $? # will always output '0' 
1
14 дек. Cavab hər hansı bir verilmişdir. 2011-12-14 15:41 '11 at 15:41 2011-12-14 15:41

type -P cmd , POSIX-uyğun env -i type cmd 1>/dev/null 2>> istifadə edə bilərik.

 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> || { echo "$cmd not found"; exit 1; } 
1
01 июня '11 в 20:49 2011-06-01 20:49 cavab 01 iyun '11 saat 20:49 'də verilir 2011-06-01 20:49

POSIX_BUILTINS parametri <command> parametri üçün təyin edildiyində -v əmri yaxşı işləyir, lakin əgər baş verməzsə, baş verə bilər. (o, mənim üçün illərdir işləmiş, lakin son vaxtlarda işləməmişdi).

Aşağıdakıları daha etibarlı hesab edirəm:

 test -x $(which <command>) 

Çünki bu 3 şeyi yoxlayır: yol, varlıq və yerinə yetirmək üçün icazə.

1
25 июня '18 в 19:53 2018-06-25 19:53 cavab AnthonyC 25 iyun '19 saat 19:53 2018-06-25 19:53' də verilir

Proqram, mövcud olduğu yerdən asılı olaraq sizə xəbər verəcəkdir.

 if [ -x /usr/bin/yum ]; then echo This is Centos fi 
1
27 нояб. Cavab 27 noyabr Klevin Kona tərəfindən verilir . 2018-11-27 19:03 '18 saat 19:03 'da 2018-11-27 19:03

İkincisi, -v komandanlığı istifadə edin. Məsələn, məsələn:

 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 
1
06 нояб. Cavab 06 noyabr tarixində user2961933 tərəfindən verilir. 2013-11-06 22:06 '13 at 10:06 pm 2013-11-06 22:06

Mən çox sadə olduğundan istifadə edirəm:

 if [ `> 

və ya

 if [ `> 

Bu, stdout üçün stilüstü və heç bir şey stderr üçün heç bir şey, əgər skript tapılmadıysa, yalnız stderr üçün echos statusuna malikdir.

0
22 сент. Cavab 22 sentyabr tarixində verilir. 2015-09-22 03:41 '15 at 3:41 'de 2015-09-22 03:41

Script

 #!/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"' 

Nəticə

 ✘ [ABRT]: notacmd: command does not exist hits command 0 /usr/bin/bash Fin. 
0
06 сент. Cavab verilir . 2017-09-06 03:42 '17 də 3:42 2017-09-06 03:42
 GIT=/usr/bin/git # STORE THE RELATIVE PATH # GIT=$(which git) # USE THIS COMMAND TO SEARCH FOR THE RELATIVE PATH if [[ ! -e $GIT ]]; then # CHECK IF THE FILE EXISTS echo "PROGRAM DOES NOT EXIST." exit 1 # EXIT THE PROGRAM IF IT DOES NOT fi # DO SOMETHING ... exit 0 # EXIT THE PROGRAM IF IT DOES 
-1
16 апр. Da'jur tərəfindən 16 apreldə cavab verildi 2017-04-16 04:21 '17 'da 4:21' də 2017-04-16 04:21 'də

git CI server yerləşdirməsinin bir hissəsi kimi quraşdırıldığını yoxlamaq məcburiyyətindəyəm. Son bash skriptim aşağıdakı kimi idi (Ubuntu server):

 if ! builtin type -p git  then sudo apt-get -y install git-core fi 

Bu başqasına kömək edir!

-1
08 апр. Greg K 08 apr tərəfindən verilən cavab . 2011-04-08 18:30 '11 at 18:30 'da 2011-04-08 18:30
  • 1
  • 2

tags ilə bağlı digər suallar və ya bir sual