特定の戻りコードをすぐに返すUnixコマンド?


28

以下の私の例に似た何かをする標準のUnixコマンドはありますか

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

<cmd here>forkで実行できるもので、プロセスの終了時に終了コードとして56を残すものでなければなりません。exitそしてreturnシェル組み込みコマンドは、私はそれから出たことで、彼らが起動したシェル自体に影響を与えるので、探しています何のためには適していません。<some cmd>は、シェル以外のコンテキストで実行できるものである必要がありますsubprocess。たとえば、を使用してPythonスクリプトから呼び出します。

たとえば、/usr/bin/false常にリターンコード1で直ちに終了しますが、そのリターンコードを正確に制御したいと思います。独自のラッパースクリプトを記述することで同じ結果を得ることができました

$ 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

しかし、私のためにこれを行うことができる標準のUnixコマンドが存在することを望んでいます。


10
exit私が考えることができる唯一のものですが、それはあなたのシェルを終了する傾向があります。 bash -c 'exit 56'またはbash -c "exit $1"あなたのために働くかもしれません。
ティムケネディ

12
どう(exit 56)
cuonglm

6
これは本当にXYProblemのように聞こえます。これの最終的な目標は何ですか?終了コードとして指定した番号を返すコマンドが必要なのはなぜですか?
オリビエデュラック

1
さて、0または1を返す必要がある場合は、trueおよびfalseがあります。
gardenhead

1
関連:(非ポータブル)コンパイル時の固定値を返す最小のプログラム:muppetlabs.com/~breadbox/software/tiny/teensy.html
Florian Castellane

回答:


39
  1. returnベースの機能が動作し、かつ(につきとして、別のシェルを開き、閉じる必要が避けられるだろうティム・ケネディさんにコメントを):

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

    出力:

    56
  2. exitサブシェルで使用する:

    (exit 56)

    以外のシェルでksh93は、余分なプロセスをフォークすることを意味するため、上記よりも効率が低下します。

  3. bash/ zsh/ ksh93トリックのみ:

    . <( echo return 56 )

    (これは、追加のプロセス(およびパイプを使用したIPC)も意味します)。

  4. zshのラムダ関数:

    (){return 56}

いい考えだ。残念ながら、私の最初の質問は十分に定義されていませんでした-「別のシェルを開いて閉じる」必要があることは、私がやりたいことのほとんどの要件でした。私は質問を編集して、それ<some cmd>がexecve()可能なものであることを要求しました。
クリス

2
@Chris:どのシェルコマンドでも、次のように変換することでexecve()可能にできます/bin/sh -c ...originalcommand...
。psmears

3
?= 56が機能しないことに少しがっかりしています。
ジョシュア

@ジョシュア:多分そうですか?しかし、その後、この愛情は成功し、あなたは$を持っていますか?0に設定...;)
オリビエデュラック

@OlivierDulac:そうではありません。解析エラーを吐き出します。
ジョシュア

17

特定の値を返すための標準的なUNIXコマンドはありません。GNUコアユーティリティは以下を提供しtruefalse唯一の機能です。

ただし、次のように簡単に実装できますret

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

コンパイル:

cc ret.c -o ret

そして実行:

./ret 56 ; echo $?

プリント:

56

余分なツールをインストールせずにどこでも(つまりbashが利用できる)これを動作させる必要がある場合は、コメントで@TimKennedyが示唆したように、次のコマンドに頼る必要があるでしょう。

bash -c 'exit 56'

戻り値の有効範囲は0..255であることに注意してください。


1
trueまたfalse、GNUだけでなく、Unix(およびPOSIX)にもあります。
ステファンシャゼラス

@StéphaneChazelasそれを指摘してくれてありがとう。OPがbashに言及したように、質問自体は「Unix」と述べていても、どういうわけかGNUを想定していました。
tmh

14

実行されたコマンドによって終了ステータスを設定する必要がある場合。その1専用のコマンドはありませんが、任意の終了ステータスで終了する機能を持つ任意の言語のインタープリターを使用できます。sh最も明白なものです:

sh -c 'exit 56'

ほとんどのsh実装では、終了コード0から255に制限されます(shより大きな値を受け入れますが、それを切り捨てるか、実行中のプロセスにシグナルを送信することさえありますsh、コード257から320のksh93のようにます)。

終了コードには任意の整数(int)値を使用waitid()できますが、値が8ビットに切り捨てられないように、インターフェースで取得する必要があることに注意してください(Linuxでは、waitid()ます)。したがって、255を超える終了コードを使用することはめったにありません(良い考えではありません)(通常の操作には0-123を使用します)。

代わりに:

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

(終了コードを8ビットに切り捨てないでください)。

NetBSD findでは、次のことができます。

find / -exit 56

1exitはそれを行うための標準コマンドですが、シェルの特殊なビルトインであるため、通常のビルトインのようにファイルシステムにその名前のコマンドが存在する必要はなく、ほとんどのシステムには含まれません


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]);
}

これをreturncode.cand という名前のファイルに保存しますgcc -o returncode returncode.c


半関連のノートで:1)affirmerとして自分自身を命名することなく、CC0ライセンスを適用し、おそらく良いアイデアではない、とあなたがそれを行う必要があり、このように、2)プログラムこの小さいあなたの著作権は関係するのはあまりにも些細な、あなたので、ライセンスを除外することもできます。
ライモイド

2
(1)のargv[argc-1]代わりにあなたが使用argv[1]している理由と、なぜ文句を言わないのか理解できませんargc>2。(2)argv[1]テストの前にargv[0]テストを行い、ユーザーがの代わりに、true 56またはのfalse 56代わりに言うことができるようにしますreturncode 56。もしargv[0]単語であるなら、あなたはメッセージを与えませんargc>0—それは混乱するかもしれません。(3)私は使いやすさにこだわっているので、strcasecmp代わりにを使用しますstrcmp。(4)パラメーターを検証する傾向があり、検証atoiせずにの戻り値を使用しません。このような2¢プログラムの場合、それは問題ではないと思います。
G-Manは「Reinstate Monica」と言います

@ G-Man Linuxシステムでは引数truefalse処理もしない
ThePiercingPrince

OK、それは正しいです-彼らは引数を処理しませんargv[0]; プログラム/bin/true/bin/falseは、ハードコードされた終了コードを含む、異なる実行可能ファイルです。と(リンク)の両方 としてインストールできるプログラムを作成しましたが、これは賢い方法です。しかし、質問はユーザー指定の終了ステータスを取得する方法を尋ねます。プログラムはその質問に答えますが、異なるファイル名でインストールされている場合のみです。とにかく見ている限り、3番目のリンクの必要性を回避することにより、賢明さのレベルを維持することをお勧めします。truefalseargv
G-Manは「Reinstate Monica」と言います

0

exitコマンドに関するあなたの唯一の問題が現在のシェルを終了することであったかどうかははっきりしませんでしたが、そうであれば、サブシェルが機能するかもしれません。

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

私は今これをCygwin Bashでテストしましたが、うまくいきました。

編集:申し訳ありませんが、シェルコンテキスト外で実行する部分を見逃しました。その場合、thsiは.shスクリプト内にラップして環境から実行せずには役に立ちません。


4
$(exit 42)は、exit 42ほとんど意味のない単純なコマンドとしての出力を実行しようとします(これもで動作しませんyash)。(exit 42)(これもexitサブシェルで実行されますが、出力はそのままです)より意味があり、より移植性があります(cshまたはBourneシェルでも)。
ステファンシャゼラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.