Amikor egy futtatható fájl elérési útját keresi, vagy ellenőrzi, mi történne, ha a parancs nevét beírja a Unix héjba, rengeteg különféle segédprogram található ( which
, type
, command
, whence
, where
, whereis
, whatis
, hash
, stb.).
Gyakran halljuk, hogy a which
-t el kell kerülni. Miért? Mit használjunk helyette?
Megjegyzések
több okból is téves (hiányzik a--
, hiányzó idézőjelek), nemcsak awhich
használata. ‘ használhatja astat -- "$(command -v ls)"
alkalmazást. Ez feltételezi, hogy als
valóban a fájlrendszeren található parancs (nem a shell beépített része vagy az alias funkciója). Awhich
hibás elérési utat adhat meg (nem azt az utat, amelyet a héj végrehajtana, ha beírja als
), vagy a megadott alias-t adja meg néhány más héj konfigurációjában …
which
megvalósítás még a ls
, amelyet a $PATH
keresésével találhatunk meg (függetlenül attól, hogy mi ls
hívhat a héjában). A sh -c 'command -v ls'
vagy a zsh -c 'rpm -q --whatprovides =ls'
nagyobb valószínűséggel adja meg a helyes választ. A lényeg itt az, hogy a which
a csh
törött öröksége. Válasz
Itt minden, amit soha nem gondolt, hogy soha nem akar tudni erről:
Összegzés
A egy Bourne-szerű shell szkript futtatható fájljának elérési útja (néhány megjegyzés található; lásd alább):
ls=$(command -v ls)
Annak kiderítése, hogy létezik-e egy adott parancs:
if command -v given-command > /dev/null 2>&1; then echo given-command is available else echo given-command is not available fi
Egy interaktív Bourne-szerű shell parancsára:
type ls
A which
parancs a C-Shell törött öröksége, és jobb, ha egyedül marad a Bourne-szerű héjakban.
Esetek használata
Ott “Megkülönböztethető az információ keresése egy szkript részeként vagy interaktív módon a shell parancssorban.
A shell parancssorban a tipikus használati eset a következő: ez a parancs furcsán viselkedik, használom a igaz? Mi történt pontosan, amikor beírtam a következőt: mycmd
? Megnézhetem tovább, mi ez?
Ebben az esetben tudni szeretné, hogy mit csinál a héja, amikor a parancs tényleges meghívása nélkül hívja meg a parancsot.
A shell szkriptekben általában egészen más. Egy shell szkriptben nincs ok arra, hogy miért akarod tudni, hogy hol vagy mi a parancs, ha csak azt akarod végrehajtani. Általában azt akarja tudni, hogy a futtatható fájl elérési útja, így több információt hozhat ki belőle (például egy másik fájl elérési útját ehhez képest, vagy információkat olvashat a futtatható fájl tartalmából ezen az útvonalon).
Interaktív módon érdemes tudni a rendszeren elérhető my-cmd
parancsok összes ről, parancsfájlokban, ritkán.
A rendelkezésre álló eszközök többségét (ahogy az gyakran előfordul) interaktív használatra tervezték.
Előzmények
Először egy kis előzmény.
A korai Unix héjak a 70-es évek végéig nem voltak funkciók vagy álnevek. Csak a futtatható fájlok hagyományos keresése a $PATH
fájlban. A csh
álneveket 1978 körül vezetett be (bár csh
először kiadták a 2BSD
, 1979 májusában), valamint egy .cshrc
feldolgozása a felhasználók számára a héj testreszabásához (minden héj, mint csh
, a .cshrc
szöveget olvassa el, még akkor is, ha nem interaktív, mint a szkripteknél.) később (1984 az SVR2-ben), és egyébként sem volt soha rc
fájl (a .profile
a környezet konfigurálása, nem a shell önmagában ).
csh
sokkal népszerűbb lett, mint a Bourne-héj, mivel (bár a szintaxisa szörnyen rosszabb volt, mint a Bourne shell) sokkal kényelmesebb és kellemesebb funkciókat adott az interaktív használathoz.
A 3BSD
(1980) cikkben >
which
csh szkriptet adtak hozzá acsh
felhasználók számára, hogy segítsenek egy futtatható fájl azonosításában, és “alig különbözõ szkriptet találsz, amelywhich
manapság számos kereskedelmi egységen (például Solaris, HP / UX, AIX vagy Tru64).
Ez a szkript beolvassa a felhasználó” s ~/.cshrc
(mint az összes csh
szkript, hacsak nem hívják meg csh -f
-vel), és megkeresi a megadott parancsneveket az álnevek és a $path
(a csh
által fenntartott tömb a $PATH
alapján).
Tessék: which
az első helyet érte el az akkori legnépszerűbb héjnál (és a csh
még a közepéig népszerű volt. 90-es évek), ami a fő ok, amiért dokumentálták a könyvekben, és továbbra is széles körben használják.
Ne feledje, hogy még csh
felhasználó esetében is az a which
csh szkript nem feltétlenül adja meg a megfelelő információkat. Megkapja a ~/.cshrc
fájlban definiált álneveket, nem pedig azokat, amelyeket később a parancssorban, vagy például source
másik csh
fájlt, és (bár ez nem lenne jó ötlet), PATH
lehet, hogy újradefiniálják a ~/.cshrc
.
A which
parancs futtatása egy Bourne-héjból továbbra is a ~/.cshrc
-ben megadott álneveket keresi, de ha nincs ilyen, mert nem használja a csh
szolgáltatást, akkor valószínűleg még mindig a megfelelő választ kapná.
Hasonló funkciót nem adtak hozzá a Bourne-héj 1984-ig az SVR2-ben a type
beépített paranccsal. Az a tény, hogy beépített (szemben egy külső szkriptel) azt jelenti, hogy tud adni (bizonyos mértékben) megfelelő információkat, mivel hozzáfér a héj belső részéhez.
A kezdeti type
parancs hasonló problémát szenvedett, mint a which
parancsfájl, mivel nem adta vissza a hiba kilépési állapotát, ha A parancs nem található. Ezenkívül a futtatható fájlok esetében, ellentétben a which
-vel, a ls is /bin/ls
-hez hasonló értéket ad ki a ami megkönnyítette a szkriptekben való használatát.
A Unix 8-as verziójú (vadon nem kiadott) Bourne-héj” s type
builtin átnevezve whatis
-re. És a Plan9 (a Unix egyszeri utódja) shell rc
(és annak olyan származékok, mint akanga
és es
) whatis
is vannak.
A Korn héj (amelynek részhalmaza a A 80-as évek közepén kifejlesztett, de 1988 előtt nem széles körben elérhető POSIX sh
definíción alapszik) sok csh
funkciót ( vonalszerkesztő, álnevek …) a Bourne-héj tetején. Hozzáadta a saját whence
beépített részét (az type
mellett), amely több lehetőséget is igénybe vett (-v
a type
-szerű verbózus kimenettel, és -p
csak futtatható fájlok keresésére (nem álnevek / függvények …)) .
Az AT & T és Berkeley közötti szerzői jogi kérdésekkel kapcsolatos zűrzavar egyidejűleg néhány ingyenes szoftver héj implementáció következett a 80-as évek végén, a 90-es évek elején.Az összes Almquist héj (ash
, amely a Bourne-héj cseréje a BSD-kben), a ksh
(pdksh
), bash
(az FSF támogatása), zsh
1989 és 1991.
Ash, bár a Bourne-héj helyettesítésére szánta, csak később volt type
beépítve (a NetBSD 1.3-ban és a FreeBSD 2.3-ban) ), bár hash -v
volt benne. Az OSF / 1 /bin/sh
beépített type
volt, 0-t adott vissza az OSF / 1 v3.x-re. bash
nem adott hozzá whence
-t, de hozzáadott egy -p
opció a type
lehetőségre az útvonal kinyomtatásához (type -p
olyan lenne, mint whence -p
) és -a
a megfelelő parancsok összes jelentéséhez. tcsh
which
beépítettet készített, és hozzáadott egy where
parancsot, amely úgy működik, mint bash
” s type -a
. zsh
mindegyik megvan.
A fish
shell (2005) type
parancsot hajtott végre függvényként.
A which
a csh szkriptet időközben eltávolították a NetBSD-ből (mivel a tcsh-ben építették be, és más kagylóban nem sokat használtak), és a funkcionalitás hozzáadódott a whereis
fájlhoz (amikor which
, whereis
úgy viselkedik, mint which
, azzal a különbséggel, hogy csak a ). Az OpenBSD-ben és a FreeBSD-ben a which
szintén C-re írtra változott, és csak $PATH
.
Megvalósítások
Tucatnyi megvalósítás létezik egy which
co mmand különféle szintaxisú és viselkedésű Unice-okon.
Linuxon (a beépítettek mellett a tcsh
és zsh
) számos megvalósítást találunk. A legújabb Debian rendszereken például “egy egyszerű POSIX shell parancsfájl, amely parancsokat keres a $PATH
fájlban.
busybox
rendelkezik egy which
paranccsal is.
Van egy GNU
which
, amely valószínűleg a leg extravagánsabb. Megpróbálja kiterjeszteni a which
csh parancsfájl más héjakra is: elmondhatja neki, hogy mik az álnevei és funkciói, hogy megadhassa jobb választ adsz neked (és úgy gondolom, hogy egyes Linux disztribúciók bizonyos globális álneveket állítanak köré a bash
számára).
zsh
van pár operátora , amely kibővíthető a futtatható fájlok elérési útjára: a =
fájlnévbővítés operátor és a :c
előzménybővítő módosító (itt a paraméterbővítés re vonatkozik):
$ print -r -- =ls /bin/ls $ cmd=ls; print -r -- $cmd:c /bin/ls
zsh
, a modul a parancs hash tábláját is létrehozza commands
asszociatív tömbként:
$ print -r -- $commands[ls] /bin/ls
A whatis
segédprogram (kivéve a Unix V8 Bourne-héjban vagy a 9. tervben szereplő rc
/ es
) valójában nem kapcsolódik, mivel csak dokumentációra szolgál (megkapja a whatis adatbázist, vagyis a man oldal szinopszisát).
whereis
szintén hozzáadva a 3BSD
fájlba egyidejűleg a which
fájlba, bár C
-ban írták, csh
és egyszerre keresésre, a futtatható fájlra, a man oldalra és a forrásra használják, de nem az aktuális környezet alapján. Tehát megint ez válaszol egy másik igényre.
Most a POSIX a szokásos fronton megadja a command -v
és -V
parancsok (amelyek korábban POSIX 2008-ig nem kötelezőek voltak). A UNIX megadja a type
parancsot (nincs opció). Ez az összes (where
, which
, whence
nincs meghatározva egyetlen szabványban sem) .
Bizonyos verziókig a type
és a command -v
opcionális volt a Linux Standard Base specifikációban, ami megmagyarázza, miért Például a (z) posh
néhány régi verziója (bár a pdksh
alapján mindkettő volt) egyikének sem volt. command -v
is hozzá lett adva néhány Bourne shell-implementációhoz (például a Solaris-hoz).
Állapot ma
Manapság az az állapot, hogy type
és command -v
mindenütt mindenütt jelen van a Bourne-szerű héjak (bár, amint azt @jarno megjegyezte, vegye figyelembe a figyelmeztetést / hibát bash
-ben, ha nincs POSIX módban, vagy az Almquist shell néhány leszármazottját a megjegyzésekben). A tcsh
az egyetlen héj, ahová a which
-t szeretné használni (mivel nincsenek type
ott van, és which
be van építve).
A tcsh
és , which
megmondhatja az adott futtatható fájl elérési útját, mindaddig, amíg ~/.cshrc
, ~/.bashrc
vagy bármelyik shell indítófájl, és nem definiálja a $PATH
elemet a
. Ha definiál egy álnevet vagy funkciót, akkor lehet, hogy elárulja, vagy nem, vagy rosszat mond.
Ha tudni akarod az összes megadott néven futó parancsról nincs semmi hordozható. Használja a where
elemet a tcsh
vagy zsh
, bash
vagy zsh
, whence -a
a ksh93-ban és más héjakban , használhatja az type
-t az which -a
vel kombinálva, amelyek működhetnek.
Ajánlások
A futtatható fájl elérési útjának megszerzése
A futtatható fájl elérési útjának megszerzéséhez egy szkriptben van néhány figyelmeztetés:
ls=$(command -v ls)
lenne a szokásos módja ennek.
Ennek ellenére van néhány probléma:
- Nem lehet tudni a futtatható fájl útvonalát végrehajtás nélkül. a
type
,which
,command -v
… mindegyik heurisztikát használ az út megtalálásához . Végiglépnek a$PATH
összetevőkön, és megtalálják az első nem könyvtárfájlt, amelyre engedélyt ad. A parancs végrehajtásakor a parancsértelmezőn sokan közülük (Bourne, AT & T ksh, zsh, ash …) csak végrehajtják őket a sorrendben.$PATH
, amíg aexecve
rendszerhívás nem tér vissza hibával. Például, ha a$PATH
/foo:/bar
-t tartalmaz, és szeretné végrehajtani als
parancsot, akkor először megpróbálják/foo/ls
végrehajtásához, vagy ha ez nem sikerül/bar/ls
. A/foo/ls
végrehajtása sikertelen lehet, mert nem rendelkezik végrehajtási engedéllyel, hanem sok más okból is, például nem érvényes futtatható fájlként.command -v ls
jelenteni fogja/foo/ls
, ha rendelkezik végrehajtási engedéllyel a/foo/ls
fájlhoz, de fut als
valóban futhat/bar/ls
, ha a/foo/ls
nem érvényes futtatható. - ha a
foo
beépített vagy függvény vagy álnév, akkorcommand -v foo
visszatér a következőhöz:foo
. Néhány olyan héjnál, mintash
,pdksh
vagyzsh
, visszatérhet afoo
ha a$PATH
tartalmazza az üres karakterláncot, és van egy futtathatófoo
fájl az aktuális könyvtárban. Vannak olyan esetek, amikor ezt figyelembe kell vennie. Ne feledje például, hogy a beépítettek listája a shell implementációjától függően változik (példáulmount
néha beépített a busybox számárash
), és példáulbash
funkciókat kaphat a környezettől. - ha relatív útvonalkomponenseket tartalmaz (általában
.
vagy az üres karakterláncot, amelyek mind az aktuális könyvtárra utalnak, de bármi lehetnek), a héjtól függően,command -v cmd
lehet, hogy nem ad ki abszolút elérési utat. Tehát az útvonal, amelyet a többé nem lesz érvényes, miutáncd
valahol máshol volt. - Anekdotikus: a ksh93 héjjal, ha
/opt/ast/bin
(bár ez a pontos elérési út eltérhet a különböző rendszerektől, úgy gondolom) benned van$PATH
, a ksh93 elérhetővé teszi néhány extra beépített programot (chmod
,cmp
,cat
…), decommand -v chmod
akkor is visszatér/opt/ast/bin/chmod
, ha az elérési út nem létezik.
A parancs létezésének meghatározása
Ha meg szeretné tudni, hogy egy adott parancs létezik-e szabványosan, akkor tegye a következőket:
if command -v given-command > /dev/null 2>&1; then echo given-command is available else echo given-command is not available fi
Ahol érdemes használni a which
(t)csh
A csh
és tcsh
csoportokban nincs sok választási lehetősége. A tcsh
mezőben ez “rendben van, mivel which
beépítve van. A csh
fájlban ez lesz a rendszer which
parancs, amely néhány esetben nem biztos, hogy azt teszi, amit akar.
Parancsok keresése csak néhány héjban
Előfordulhat, hogy van értelme a which
használatának, ha meg akarja ismerni a parancs útját, figyelmen kívül hagyva a potenciált beépített shellek vagy a bash
, csh
(nem tcsh
), dash
vagy Bourne
shell szkriptek, vagyis olyan héjak, amelyek nem rendelkeznek whence -p
(például ksh
vagy zsh
), command -ev
(például yash
), whatis -p
(rc
, akanga
) vagy beépített which
(például tcsh
vagy zsh
) olyan rendszereken, ahol which
elérhető, és nem a csh
szkript.
Ha ezek a feltételek teljesülnek, akkor:
echo=$(which echo)
megadná az első echo
a $PATH
-ban (a sarok esetek kivételével), függetlenül attól, hogy a echo
is héj-e beépített / alias / function, vagy sem.
Más héjakban inkább:
- zsh :
echo==echo
vagyecho=$commands[echo]
vagyecho=${${:-echo}:c}
- ksh , zsh :
echo=$(whence -p echo)
- yash :
echo=$(command -ev echo)
- rc , akanga :
echo=`whatis -p echo`
(óvakodj a szóközökkel rendelkező utaktól) - hal :
set echo (type -fp echo)
Ne feledje, hogy ha csak annyit szeretne csinálni, akkor futtassa azt a echo
parancsot, akkor nem kell elérnie az útvonalát, csak megteheti:
env echo this is not echoed by the builtin echo
Például a tcsh
paranccsal, hogy megakadályozza a beépített which
használatát:
set Echo = "`env which echo`"
Ha külső parancsra van szükség
Egy másik eset, amikor érdemes használni a which
alkalmazást, amikor valójában szüksége van egy külső parancs. A POSIX megköveteli, hogy az összes shell beépített program (például command
) külső parancsként is elérhető legyen, de sajnos ez nem így van a command
sok rendszeren. Például ritkán található command
parancs Linux alapú operációs rendszereken, míg a legtöbbjüknek which
parancs (bár különbözőek, különböző opciókkal és viselkedéssel).
Azokban az esetekben, amikor külső parancsra van szükség, bárhová futtatnának egy parancsot POSIX héj meghívása nélkül.
A system("some command line")
, popen()
… a C vagy különféle nyelvek függvényei héjat hívnak meg a parancssor elemzéséhez, ezért system("command -v my-cmd")
munkát végeznek bennük. Ez alól kivételt jelentene az perl
, amely optimalizálja a héjat, ha nem lát semmilyen shell speciális karaktert (a szóköz kivételével). Ez vonatkozik a backtick operátorára is:
$ perl -le "print system "command -v emacs"" -1 $ perl -le "print system ":;command -v emacs"" /usr/bin/emacs 0 $ perl -e "print `command -v emacs`" $ perl -e "print `:;command -v emacs`" /usr/bin/emacs
A fenti :;
hozzáadása perl
parancsértelmező meghívására kényszeríti A which
használatával nem kell ezt a trükköt használni.
Megjegyzések
- @Joe,
which
egycsh
szkript számos kereskedelmi egységben. Az ok történelmi, hogy ‘ miért adtam át az előzményeket, hogy az emberek megértsék, honnan származik, miért szokták meg az emberek és miért is valójában ott vannak ‘ nincs ok arra, hogy használnod kell. És igen, egyesek a (t) csh-t használják. Még nem mindenki használja a Linuxot - A bejegyzés elolvasása után sok összefüggést találtam a válaszra, de nem magát a választ.Hol található ebben a bejegyzésben, miért nem használja a
which
-t, szemben olyan dolgokkal, amelyeket esetleg megpróbál használniwhich
tennivaló, awhich
előzményei, awhich
megvalósításai, egyéb parancsok a kapcsolódó feladatok elvégzéséhez, vagy a tényleges használat okaiwhich
? Miért jobb a többi parancs jobb ? Mit csinálnak másképp, mint awhich
? Hogyan kerülhetik el a buktatókat? Ez a válasz valójában több szót fordít az alternatívák problémáira, mint awhich
problémáira. -
command
POSIX által. - @St é phaneChazelas Ha új fájlt hozok létre
touch /usr/bin/mytestfile
által, majd futtatom acommand -v mytestfile
, megadja az elérési utat (mígwhich mytestfile
nem). - @jarno, igen, te ‘ igaza van.
bash
egy nem futtatható fájlra települ, ha ‘ nem talál futtatható fájlt, tehát ‘ s ” OK ” (bár a gyakorlatban inkábbcommand -v
/type
hibát ad vissza), mivel ez a ‘ s az a parancs, amelyet megpróbál végrehajtani, amikor futtatja a , de adash
viselkedés hibás, mintha ‘ nem futtathatócmd
egy futtatható előtt,command -v
visszaadja a nem futtathatót, miközben acmd
futtatja a futtathatót (rossz az egyik is hash). A FreeBSDsh
(szintén aash
alapján) ugyanaz a hiba. zsh, yash, ksh, mksh, bash as sh rendben vannak.
Válasz
Az okok nem akarja használni a which
kifejezést már elmagyarázták, de íme néhány példa néhány olyan rendszerre, ahol a which
valóban meghibásodik.
Bourne-szerű héjakon összehasonlítjuk a which
kimenetét a type
(type
mivel egy beépített héj, ez az alapigazság, mivel a héj megmondja nekünk, hogyan hívja meg a parancsot.
Sok esetben corner esetek, de ne feledje, hogy which
/ type
gyakran használják sarok esetekben (a válasz megtalálásához váratlan viselkedésre, például: miért a földön viselkedik ez a parancs így, melyiket hívom? ).
A legtöbb rendszer, a legtöbb Bourne-szerű héj: funkciók
A legkézenfekvőbb eset a függvényekre vonatkozik:
$ type ls ls is a function ls () { [ -t 1 ] && set -- -F "$@"; command ls "$@" } $ which ls /bin/ls
Ennek az az oka, hogy a which
csak a futtatható fájlokról és néha álnevekről (bár nem mindig a te héjadról) számol be, nem pedig funkciókról.
Az a GNU, amelyik man oldalnak meghibásodott (mivel elfelejtették idézni az $@
idézetet) példa arra, hogyan kell használni a funkciók jelentésére is, de csakúgy, mint álnevek, mivel nem valósítja meg a shell szintaxis elemzőjét, ezért könnyen becsapja:
$ which() { (alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot "$@";} $ f() { echo $"\n}\ng ()\n{ echo bar;\n}\n" >> ~/foo; } $ type f f is a function f () { echo " } g () { echo bar; } " >> ~/foo } $ type g bash: type: g: not found $ which f f () { echo " } $ which g g () { echo bar; }
A legtöbb rendszer, a legtöbb Bourne-szerű shell: beépített
Egy másik nyilvánvaló eset a beépített elemek vagy kulcsszavak, mivel a which
külső parancs nem tudja tudni, hogy melyik beépített héja van a héjnak (és néhány olyan héj, mint a zsh
, bash
vagy ksh
dinamikusan be tudja tölteni a beépítetteket):
$ type echo . time echo is a shell builtin . is a shell builtin time is a shell keyword $ which echo . time /bin/echo which: no . in (/bin:/usr/bin) /usr/bin/time
(ez nem vonatkozik a zsh
elemre, ahol which
be van építve)
Solaris 10, AIX 7.1, HP / UX 11i, Tru64 5. 1 és még sokan mások:
$ csh % which ls ls: aliased to ls -F % unalias ls % which ls ls: aliased to ls -F % ksh $ which ls ls: aliased to ls -F $ type ls ls is a tracked alias for /usr/bin/ls
Ennek az az oka, hogy a legtöbb kereskedelmi egységben which
(mint az eredeti megvalósításban) a 3BSD-n) egy csh
parancsfájl, amely a következőt írja: ~/.cshrc
. Az általa jelentett álnevek az ott definiált álnevek, függetlenül a jelenleg definiált álnevektől és a ténylegesen használt héjatól.
HP / UX vagy Tru64 esetén:
% echo "setenv PATH /bin:/usr/bin" >> ~/.cshrc % setenv PATH ~/bin:/bin:/usr/bin % ln -s /bin/ls ~/bin/ % which ls /bin/ls
(a Solaris és az AIX verzió kijavította ezt a problémát a $path
mentésével, mielőtt elolvasta a ~/.cshrc
és visszaállítása a parancs (ok) megkeresése előtt)
$ type "a b" a b is /home/stephane/bin/a b $ which "a b" no a in /usr/sbin /usr/bin no b in /usr/sbin /usr/bin
Vagy:
$ d="$HOME/my bin" $ mkdir "$d"; PATH=$PATH:$d $ ln -s /bin/ls "$d/myls" $ type myls myls is /home/stephane/my bin/myls $ which myls no myls in /usr/sbin /usr/bin /home/stephane/my bin
(természetesen csh
parancsfájlként nem várhatjuk el, hogy szóközöket tartalmazó argumentumokkal működjön …)
CentOS 6.4, bash
$ type which which is aliased to `alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde" $ alias foo=": "|test|"" $ which foo alias foo=": "|test|"" /usr/bin/test $ alias $"foo=\nalias bar=" $ unalias bar -bash: unalias: bar: not found $ which bar alias bar="
Ezen a rendszeren egy egész rendszerre definiált álnév van, amely beburkolja a GNU which
parancsot.
A hamis kimenet azért van, mert a which
beolvassa a bash
“s alias
de nem tudja, hogyan kell megfelelően elemezni, és heurisztikát használ (soronként egy alias, az első megtalált parancsot keresi egy |
, , &
…)
A CentOS legrosszabb dologja, hogy zsh
egy teljesen finom which
beépített parancs, de a CentOS sikerült megtörnie azzal, hogy egy nem működő aliasra cserélte GNU which
.
Debian 7.0, ksh93:
(bár a legtöbb kagylóval rendelkező rendszerre vonatkozik)
$ unset PATH $ which which /usr/local/bin/which $ type which which is a tracked alias for /bin/which
A Debianon /bin/which
egy /bin/sh
szkript. Az én esetemben sh
dash
, de ugyanaz, ha “s bash
.
Egy unset PATH
nem az PATH
keresés letiltása, hanem a “s alapértelmezett PATH amivel sajnos a Debianon senki sem ért egyet (dash
és bash
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
, zsh
/bin:/usr/bin:/usr/ucb:/usr/local/bin
, ksh93
/bin:/usr/bin
, mksh
/usr/bin:/bin
($(getconf PATH)
), execvp()
(például env
esetén) :/bin:/usr/bin
(igen, először az aktuális könyvtárba néz!) .
Éppen ezért which
téveszti fent, mivel a dash
alapértelmezett PATH
amely eltér a ksh93
“s
Ez nem jobb, ha a GNU which
, amely beszámol:
which: no which in ((null))
(érdekes módon valóban van egy /usr/local/bin/which
a rendszeremen, ami valójában egy akanga
szkript, amely a akanga
( “>
shell származék, ahol az alapértelmezettPATH
/usr/ucb:/usr/bin:/bin:.
)))
bash, bármely rendszer:
Az a Chris, akire válaszában hivatkozik :
$ PATH=$HOME/bin:/bin $ ls /dev/null /dev/null $ cp /bin/ls bin $ type ls ls is hashed (/bin/ls) $ command -v ls /bin/ls $ which ls /home/chazelas/bin/ls
A hash
kézi hívás után is:
$ type -a which which is /usr/local/bin/which which is /usr/bin/which which is /bin/which $ hash -p /bin/which which $ which which /usr/local/bin/which $ type which which is hashed (/bin/which)
Most olyan eset van, amikor which
és néha type
nem sikerül:
$ mkdir a b $ echo "#!/bin/echo" > a/foo $ echo "#!/" > b/foo $ chmod +x a/foo b/foo $ PATH=b:a:$PATH $ which foo b/foo $ type foo foo is b/foo
Most, néhány kagylóval:
$ foo bash: ./b/foo: /: bad interpreter: Permission denied
Másokkal:
$ foo a/foo
Sem which
, sem type
előre tudhatja, hogy b/foo
nem tud b e kivégezték. Néhány héj, például bash
, ksh
vagy yash
, amikor a foo
valóban megpróbálja futtatni a b/foo
-et és hibát jelenteni, míg mások (például zsh
, ash
, csh
, Bourne
, tcsh
) futni fog a/foo
a execve()
rendszerhívás sikertelensége esetén a b/foo
.
Megjegyzések
-
mksh
valójában mást használ az alapértelmezett$PATH
esetén: először , az operációs rendszer fordítási időállandóját_PATH_DEFPATH
használják (leggyakrabban a BSD-kön), majdconfstr(_CS_PATH, …)
(POSIX), és ha mindkettő nem létezik, vagy nem sikerül, akkor a/bin:/usr/bin:/sbin:/usr/sbin
kifejezést használjuk. - Az első példában még akkor is, ha
ls
egy olyan függvény, amely usin gls
a PATH-ból. És awhich
jó, ha megmondja, melyiket használják/usr/bin/ls
vagy/usr/local/bin/ls
. Nem látom ‘ nem látom ” Miért ne használnám, melyik ” …. - @rudimeier, Ez az
which ls
/bin/ls
nekem ad, függetlenül attól, hogy als
függvényhívások/bin/ls
vagy/opt/gnu/bin/ls
vagydir
, vagy semmi. IOW,which
(ami a megvalósításokat, az IMMV) valami irrelevánsat ad - @St é phaneChazelas. Nem nem nem. Már tudom , hogy a
ls
függvényem. tudom , hogy als
függvényemls
-et hívja a következőtől:PATH
. Mostwhich
megmondja, hol van a fájl. Csak egyetlen egyszer használatos esetet lát: ” Mit csinálna a shellem ezzel a paranccsal. ” Ehhez a felhasználási esethezwhich
téves, helyes.De vannak más olyan felhasználási esetek is, amikor a (GNU)which
pontosan a helyes dolog. - @rudimeter, a
which
megvalósítás. Néhányan elmondják, hogy ‘ álnév (ha van beállítva álnév, vagy ha van otthonában~/.cshrc
ilyen álnév), néhány megad egy utat, de bizonyos feltételek mellett rossz.sh -c 'command -v ls'
, bár nem tökéletes, mégis valószínűbb, hogy megfelelő választ ad erre a különböző követelményre (és ez szintén szabványos).
Válasz
Egy dolgot (a gyors átfutásom alapján) úgy tűnik, hogy Stephane nem említette, hogy which
fogalmad sincs a héj elérési útjának hash táblájáról. Ez azt eredményezi, hogy olyan eredményt adhat vissza, amely nem reprezentatív a ténylegesen lefuttatottakhoz, ami hatástalanná teszi a hibakeresésben.
Válasz
Általában akkor összerándulok, amikor ezt a kérdést a gyanútlan felhasználóknak ajánljuk, mert a which
alaptalan alapja senkinek sem hasznos.
Ha jól működik, és helyes választ ad valamilyen feladatra, követve a Unix motívumát: csinálj egyet, csináld jól , miért kellene which
be kell tiltani?
Akkor kell feltenni a kérdést, hogy melyik működik jól, és jól teljesít-e egy adott munkát?
Az egyik esetében a / bin / melyik külső segédprogram a Debianban egy shell szkript, amelynek célja csak a megadott név futtatható fájljainak felsorolása az útvonalon. Úgy gondolom, hogy a which
helyesen teljesíti a kitűzött célt. Nem tölt be álneveket, funkciókat, semmit a shellből, csak felsorolja a PATH-ra az adott név első (vagy összes) futtatható fájlját. A jelentése, hogy a megadott névvel rendelkező fájlt talált, a felhasználónak neki (neki) kell kitalálnia önálló.
Igen, más which
megvalósításoknak lehetnek (és általában vannak) sajátos problémáik.
Válasz
Gyakran halljuk, amit el kell kerülni. Miért? Mit használjunk helyette?
Ezt még soha nem hallottam. Kérjük, adjon meg konkrét példákat. Aggódnék a Linux disztribúciód és a telepített szoftvercsomagjaid miatt, mivel innen származik a which
!
SLES 11.4 x86-64
tcsh 6.18.01 verzióban:
> which which which: shell built-in command.
a bash 3.2-147 verzióban:
> which which /usr/bin/which > which -v GNU which v2.19, Copyright (C) 1999 - 2008 Carlo Wood. GNU which comes with ABSOLUTELY NO WARRANTY; This program is free software; your freedom to use, change and distribute this program is protected by the GPL.
which
a util-linux a Linux Kernel Organization által forgalmazott szabványos csomag, amely a Linux operációs rendszer részeként használható. Ezeket a többi fájlokat is biztosítja.
/bin/dmesg /bin/findmnt /bin/logger /bin/lsblk /bin/more /bin/mount /bin/umount /sbin/adjtimex /sbin/agetty /sbin/blkid /sbin/blockdev /sbin/cfdisk /sbin/chcpu /sbin/ctrlaltdel /sbin/elvtune /sbin/fdisk /sbin/findfs /sbin/fsck /sbin/fsck.cramfs /sbin/fsck.minix /sbin/fsfreeze /sbin/fstrim /sbin/hwclock /sbin/losetup /sbin/mkfs /sbin/mkfs.bfs /sbin/mkfs.cramfs /sbin/mkfs.minix /sbin/mkswap /sbin/nologin /sbin/pivot_root /sbin/raw /sbin/sfdisk /sbin/swaplabel /sbin/swapoff /sbin/swapon /sbin/switch_root /sbin/wipefs /usr/bin/cal /usr/bin/chrp-addnote /usr/bin/chrt /usr/bin/col /usr/bin/colcrt /usr/bin/colrm /usr/bin/column /usr/bin/cytune /usr/bin/ddate /usr/bin/fallocate /usr/bin/flock /usr/bin/getopt /usr/bin/hexdump /usr/bin/i386 /usr/bin/ionice /usr/bin/ipcmk /usr/bin/ipcrm /usr/bin/ipcs /usr/bin/isosize /usr/bin/line /usr/bin/linux32 /usr/bin/linux64 /usr/bin/look /usr/bin/lscpu /usr/bin/mcookie /usr/bin/mesg /usr/bin/mkzimage_cmdline /usr/bin/namei /usr/bin/rename /usr/bin/renice /usr/bin/rev /usr/bin/script /usr/bin/scriptreplay /usr/bin/setarch /usr/bin/setsid /usr/bin/setterm /usr/bin/tailf /usr/bin/taskset /usr/bin/time /usr/bin/ul /usr/bin/uname26 /usr/bin/unshare /usr/bin/uuidgen /usr/bin/wall /usr/bin/whereis /usr/bin/which /usr/bin/write /usr/bin/x86_64 /usr/sbin/addpart /usr/sbin/delpart /usr/sbin/fdformat /usr/sbin/flushb /usr/sbin/freeramdisk /usr/sbin/klogconsole /usr/sbin/ldattach /usr/sbin/partx /usr/sbin/rcraw /usr/sbin/readprofile /usr/sbin/rtcwake /usr/sbin/setctsid /usr/sbin/tunelp
az én util-linux
a 2.19-es verzió. A kiadási megjegyzések könnyen megtalálhatók a 2007. augusztus 28-i verzióig. Nem biztos benne, mi volt ennek a célja vagy célja, és biztosan nem válaszoltak arra a hosszadalmas dologra, amely 331 alkalommal adott szavazatot.
Hozzászólások
- Vegye észre, hogy a kérdés nem tesz említést arról, hogy mire hivatkozik a Unix. A Linux csak egy a néhány közül.
- Amint a
which -v
fájlja mutatja, az a ‘ GNU, amely (az extravagáns az egyiket a másik válaszban említettem, és semmiképpen sem jellemző a Linuxra), nem a util-linux, amelyhez az AFAIK soha nem tartalmazottwhich
segédprogramot. A util-linux 2.19 2011-ből származik, a GNU pedig 2.19-ből áll.
which
használatával szembeni legtöbb érv interaktív shell-kontextust feltételez. Ez a kérdés tagged / hordozhatóság. Tehát értelmezem a kérdés ebben az összefüggésben ” néven mit használjon awhich
helyett egy adott név első futtatható fájljának megtalálásához a$PATH
“. A legtöbb válasz és indokwhich
álnevekkel, beépítettekkel és függvényekkel foglalkozik, amelyek a legtöbb valós hordozható shell szkriptben csak tudományos érdeklődésre tartanak számot. A helyileg definiált álnevek nem ‘ t öröklődnek egy shell parancsfájl futtatásakor (hacsak nem a.
címmel állítja be).csh
(éswhich
továbbra iscsh
szkript a legtöbb reklámban Unices) beolvassa~/.cshrc
, ha nem interaktív. Ezért ‘ ezért ‘ észreveszi, hogy a csh szkriptek általában#! /bin/csh -f
-vel kezdődnek. Awhich
nem azért van, mert célja az álnevek megadása, mert ‘ eszközként szolgál A (z)csh
(interaktív) felhasználói. A POSIX héjfelhasználókcommand -v
.(t)csh
(vagy nem bánja, ha ‘ nem adja meg a helyes eredményt), használja atype
vagycommand -v
helyett . Nézze meg a miért válaszokat.