Hemen belirli bir dönüş kodu döndüren Unix komutu?


28

Aşağıdaki örneğime benzer bir şey yapan standart bir Unix komutu var mı

$ <cmd here> 56
$ echo Return code was $?
Return code was 56
$

<cmd here>çatalla çalıştırılabilen ve işlem çıktığında çıkış kodu olarak 56 bırakan bir şey olmalıdır. exitVe returnkabuk yerleşikleri ben bunun dışında çıkarak onlar çağıran kabuk kendisini etkilemez çünkü aradığım şey için uygun değildir. <some cmd>kabuk dışı bağlamlarda uygulayabileceğim bir şey olmalı - örneğin, bir Python betiğinden çağırmak subprocess.

Örneğin, /usr/bin/falseher zaman dönüş kodu 1 ile hemen çıkar, ancak bu dönüş kodunun ne olduğunu tam olarak kontrol etmek isterim. Kendi sarmalayıcı betiğimi yazarak aynı sonuçları elde edebilirim

$ cat my-wrapper-script.sh # i.e., <some cmd> = ./my-wrapper-script.sh
#!/usr/bin/bash
exit $1
$ ./my-wrapper-script.sh 56
$ echo $?
56

ama umarım orada benim için bunu yapabilen standart bir Unix komutu vardır.


10
exitaklıma gelen tek şey, ama kabuğuna son verme eğiliminde. bash -c 'exit 56'veya bash -c "exit $1"sizin için çalışabilir.
Tim Kennedy,

12
Ne dersiniz (exit 56)?
cuonglm

6
Bu gerçekten bir XYProblem'e benziyor : Bunun nihai amacı nedir? Neden çıkış kodunu döndüren bir komuta ihtiyacın var?
Olivier Dulac

1
Eh, sahip trueve falsesiz 0 veya 1 dönmek gerekirse yerleşik ins
Gardenhead

1
ilgili: (taşınabilir olmayan) derleme zamanı sabit bir değer döndürmek için en küçük program: muppetlabs.com/~breadbox/software/tiny/teensy.html
Florian Castellane

Yanıtlar:


39
  1. Temel bir returnişlev işe yarar ve başka bir kabuğu açma ve kapatma gereksinimini ortadan kaldırır ( Tim Kennedy'nin yorumuna göre ):

    freturn() { return "$1" ; } 
    freturn 56 ; echo $?

    Çıktı:

    56
  2. exitbir alt kabuk kullanarak :

    (exit 56)

    Dışında mermiler varsa ksh93, bu fazladan bir sürecin çatallanması anlamına gelir, yani yukarıdakilerden daha az verimlidir.

  3. bash/ zsh/ ksh93sadece numara:

    . <( echo return 56 )

    (bu ayrıca ekstra bir işlem anlamına gelir (ve bir borulu IPC)).

  4. zsh's lambda fonksiyonları:

    (){return 56}

Güzel düşünce. Maalesef, asıl sorum yeterince iyi tanımlanmadı - “başka bir kabuğu açıp kapatmaya” ihtiyaç duymak, yapmak istediğim şeyin neredeyse bir şartıydı. <some cmd>Sorumu bunun execve () - yetenekli bir şey olmasını gerektirecek şekilde değiştirdim .
Chris

2
@Chris: Herhangi bir kabuk komutu için bunu (/bin/sh -c ...originalcommand...
psmears

3
Hafifçe hayal kırıklığına uğradım? = 56 çalışmıyor.
Joshua,

@Joshua: belki öyle mi? ama sonra bu istek başarılı oldu ve sende $ var mı? 0 ...;)
Olivier Dulac

@OlivierDulac: Öyle değil. Ayrıştırma hatası veriyor.
Joshua,

17

Sadece belirli bir değeri döndürmek için standart bir UNIX komutu yoktur. GNU Çekirdek Utilies trueve falsesadece sağlar.

Ancak bunu kendiniz kolayca uygulayabilirsiniz ret:

#include <stdlib.h>
int main(int argc, char *argv[]) {
  return argc > 1 ? atoi(argv[1]) : 0;
}

Derleme:

cc ret.c -o ret

Ve koş:

./ret 56 ; echo $?

Baskılar:

56

Herhangi bir ilave araç kurmadan her yerde (bash varsa, yani) çalışmanız gerekiyorsa, muhtemelen yorumlarda @TimKennedy'nin önerdiği şekilde aşağıdaki komuta başvurmanız gerekir:

bash -c 'exit 56'

Geçerli getiri değerleri aralığının 0,2555 olduğunu unutmayın .


1
trueve falseUnix'te (ve hatta POSIX'te), sadece GNU'da değil.
Stéphane Chazelas 10:16

@ StéphaneChazelas Buna dikkat çektiğiniz için teşekkürler. OP'nin belirttiği gibi, bir şekilde GNU'yu üstlenmiştim.
tmh

14

Çıkış durumunun bir çalıştırılan komutlar tarafından ayarlanması gerekirse. Bu 1 için özel bir komut yoktur , ancak keyfi bir çıkış durumuyla çıkma olan herhangi bir dilin tercümanını kullanabilirsiniz. shen açık olanı:

sh -c 'exit 56'

Çoğu shuygulamada, 0 ila 255 çıkış kodlarıyla sınırlıdır ( shdaha büyük değerler kabul eder, ancak bunu kısaltabilir veya hatta sh257 ila 320 kodları için ksh93 ile çalışan işleme gönderilen bir sinyale neden olabilir ).

Bir çıkış kodu herhangi bir tamsayı ( int) değer olabilir, ancak değeri waitid()arabirim ile almanız gerektiğine dikkat edin, böylece değer 8 bit olarak kesilmez (Linux'ta yine waitid()de olduğu gibi kesilir ). Bu nedenle neden 255'in üzerindeki çıkış kodlarını kullanmak nadirdir (ve iyi bir fikir değildir) (normal çalışma için 0-123 kullanın).

Alternatif:

awk 'BEGIN{exit 56}'
perl -e 'exit 56'
python -c 'exit(56)'
expect -c 'exit 56'

(bunlar çıkış kodunu 8 biti kesmiyor).

NetBSD ile findşunları yapabilirsiniz:

find / -exit 56

1exit , bunu yapmak için standart bir komuttur, ancak kabuk özel bir yerleşik olarak , normal sistemlerde olduğu gibi dosya sisteminde bu isimde bir komutun bulunmasına gerek yoktur ve çoğu sistem bunlardan birini içermez.


3
/* Public domain, http://creativecommons.org/publicdomain/zero/1.0/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char **argv) {
    if(!strcasecmp(argv[0],"true")) return 0;
    else if (!strcasecmp(argv[0],"false")) return 1;
    else if(argc<2) {fputs("One argument required\n",stderr);return 1;}
    else if(!strcasecmp(argv[argc-1],"true")) return 0;
    else if(!strcasecmp(argv[argc-1],"false")) return 1;
    else return atoi(argv[argc-1]);
}

Adlı bir dosyada bu tasarruf returncode.cvegcc -o returncode returncode.c


Yarı İlgili bir: 1) Bir affirmer olarak kendinizi adlandırma olmadan CC0 lisansı uygulayarak muhtemelen iyi bir fikir değildir ve bunu yapmalıyım böyle , 2) programları bu küçük telif hakkı önemi için çok önemsiz, senin böylece ehliyet dışında da olabilir.
Rhymoid

2
(1) Neden kullanmak argv[argc-1]yerine neden kullandığınızı argv[1]ve neden şikayet etmediğinizi anlamıyorum argc>2. (2) argv[1]Testten önce testi yapmaya argv[0], kullanıcının söylemesine true 56ya da false 56yerine söylemesine izin veririm returncode 56. Eğer argv[0]bir kelime ise ve argc>0- bu kafa karıştırıcı olabilirse , bir mesaj vermeyin . (3) Kullanıcı dostu olmak konusunda takıntılıyım, bu yüzden strcasecmpyerine kullanırdım strcmp. (4) Parametreleri onaylama eğilimindeyim ve dönüş değerini atoidoğrulamadan kullanmıyorum . Böyle bir 2 ¢ program için, önemli değil sanırım.
G-Man

G-Man @ ne truede falseLinux sistemlerinde herhangi bir argüman işler
ThePiercingPrince

Tamam, bu doğru - onlar dahil herhangi bir argümanı işleme koymuyorlar argv[0]; programlar /bin/trueve /bin/falsesabit kodlu çıkış kodları ile farklı çalıştırılabilir. Sen kurulabilir bir program yazdım hem true ve falsezeki (bağlantılı). Ancak soru, kullanıcı tarafından belirlenen bir çıkış durumunun nasıl alınacağını sorar. Programınız bu soruyu yanıtlar, ancak yalnızca farklı bir dosya adı altında yüklüyse. Yine de baktığınız sürece, argvönerdiğim şekilde yapmanın üçüncü bir bağlantıya duyulan gereksinimden kaçınarak zekâ seviyesini koruyacağına inanıyorum.
G-Man

0

Komutla ilgili tek sorununuzun exitmevcut kabuğundan çıkıp çıkmadığından tam olarak emin değildim , ancak öyleyse, bir alt kabuk işe yarayabilir.

username@host$ $(exit 42)
username@host$ echo $?
42

Bunu şimdi Cygwin Bash üzerinde test ettim ve bu benim için çalışıyor.

Düzenleme: Üzgünüm bir kabuk bağlamı dışında çalışan kısmını özledim. Bu durumda thsi, bir .shbetiğin içine koymadan ve bunu ortamınızdan yürütmeden yardımcı olmaz .


4
$(exit 42)Çok exit 42az mantıklı (aynı zamanda işe yaramayacak yash) basit bir komutun çıktısını çalıştırmaya çalışır . (exit 42)(ayrıca exitbir alt kabukta çalışır, ancak çıktısını yalnız bırakır) daha mantıklı olur ve daha taşınabilir olur (hatta csh veya Bourne kabuğuna bile).
Stéphane Chazelas 10:16
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.