コマンドを直接実行することと「bash -c」を使用することの違いは何ですか?

コマンドを直接実行することと「bash -c」を使用することの違いは何ですか?

bash -cコマンド(組み込みまたは外部)の場合、bashシェルプロセスで直接実行することとbashシェルで実行することの違いは何ですか?互いに比較すると、どのような長所と短所がありますか?

For example, in a bash shell, run `date` directly, and run `bash -c
date`. Also consider a builtin command instead of an external one.

ベストアンサー1

  1. この-cオプションを使用すると、プログラムはコマンドを実行できます。分割して実行するのははるかに簡単です。

    execl("/bin/sh", "sh", "-c", "date | od -cb  &&  ps > ps.out", NULL);
    

    フォークと比較すると、パイプを作成し、再フォークし、execl各サブパイプラインを呼び出し、呼び出し、終了wait状態を確認し、再フォークし、呼び出し、close(1)ファイルを開き、ファイル記述子1で開いていることを確認してから、他のexecl。私はこれがこのオプションが当初作られた理由だと思います。

    ライブラリsystem()関数は上記のようにコマンドを実行します。

  2. ランダムに複雑なコマンドを受け入れ、それを単純なコマンドのように見せる方法を提供します。これは、カスタムコマンド(たとえば、または)を実行するプログラムにfind … -exec役立ちますxargs。しかし、あなたはこれがあなたの質問に対する答えの一部であることをすでに知っていました。 複合コマンドを他のコマンドの引数として指定するには?
  3. これは、 bash ではなく対話型シェルを実行する場合に便利です。代わりにbashを実行している場合は、この構文を使用できます

    $ash-c"注文する
     
    $csh -c"注文する
     
    $ダッシュ-c"注文する
     
    $zsh -c"注文する

    すべてのシェルもこの-cオプションを認識するため、別のシェルでコマンドを実行してください。もちろん、次のような結果が得られます。

    $再
    再$注文する
    グレー$出口
     
    $csh
    csh$注文する
    csh$ 終了
     
    $ダッシュ
    ダッシュ$注文する
    ダッシュ$exit
     
    $ジッシュ
    zsh$注文する
    zsh$ 終了

    私はash$ 他のシェルプロンプトを説明するためになどを使用します。実際にはこれを得ることができないかもしれません。

  4. たとえば、「新しい」bashシェルでコマンドを実行したい場合に便利です。

    $ ls -lA
    total 0
    -rw-r--r-- 1 gman gman   0 Apr 14 20:16 .file1
    -rw-r--r-- 1 gman gman   0 Apr 14 20:16 file2
    
    $ echo *
    file2
    
    $ shopt -s dotglob
    
    $ echo *
    .file1 file2
    
    $ bash -c "echo *"
    file2
    

    または

    $ type shift
    shift is a shell builtin
    
    $ alias shift=date
    
    $ type shift
    shift is aliased to ‘date’
    
    $ bash -c "type shift"
    shift is a shell builtin
    
  5. 上記は誤解を招く過度に単純化された内容です。 bash の実行時に-c考慮されます。非対話型~/.bashrcシェルであり、指定しない限り読みません-i。だから、

    $タイプCP
    cp のエイリアスは「cp -i」です。          #定義済み~/.bashrc
     
    $cp .file1 ファイル 2
    cp:"file2"を上書きしますか? N
     
    $ bash -c "cp .file1 ファイル2"
                                      #既存のファイルを確認せずに上書きしました!
    $ bash -c -i "cp .file1 ファイル2"
    cp:"file2"を上書きしますか? N

    代わりに-ci-i -cまたはを使用できます。-ic-c -i

    これは、3段落に記載されている他のシェルにもある程度適用される可能性があるため、長い形式(つまり、実際に入力とまったく同じ量の2番目の形式)がより安全になります。特にinit / configファイルを設定した場合はさらにそうです。その皮。

  6. 〜のようにワイルドカードの説明、新しいプロセスツリー(新しいシェルプロセスと可能なサブプロセス)が実行されているため、サブシェルで環境が変更されます。 できない親シェル(現在のディレクトリ、環境変数の値、関数定義など)に影響します。したがって、sh -cに埋め込まれたシェルが親シェルによって開始されたバックグラウンドタスクに影響を与えたり、アクセスできなかったり、それを待つことができないことを想像することは困難です。本質的にただ実行するのと同じです。fgbgjobswaitsh -c "exec some_program"some_program対話型シェルから直接一般的な方法です。  sh -c exitそれは大きな時間の無駄です。  ulimitまた、umask子プロセスのシステム設定を変更した後、実行せずに終了することも可能です。

    コンテキストで動作するほとんど唯一の組み込みコマンドsh -cはですkill。もちろん、出力(echo、、printfおよびpwd)のみを生成するコマンドtypeは影響を受けず、ファイルに書き込んでも持続します。

  7. もちろん、組み込み機能を使用することもできます。これと組み合わせる たとえば、外部コマンド
    sh -c "CDディレクトリ;プログラム
    ただし、通常のサブシェルを使用すると、本質的に同じ効果が得られます。
    (CDディレクトリ;プログラム)
    どちらがより効率的ですか?同様のことについても同じです(2つの部分)。
    sh -c "umask 77;プログラム
    またはulimit(またはshopt)。その後に任意に複雑なコマンドを入れることができるので(フルシェルスクリプトの複雑さまで)、、、、、などの組み込み-cコマンドを使用できます。sourcereadexporttimessetunset

おすすめ記事