Bashコマンド:パラメータをカスタムコマンド(関数)の前に渡すことはできますか、それとも次の後にのみ渡すことができますか?

Bashコマンド:パラメータをカスタムコマンド(関数)の前に渡すことはできますか、それとも次の後にのみ渡すことができますか?

コマンドの前にカスタムコマンドに引数を渡すことができるかどうか疑問に思います。

pingカスタムコマンドがあり、コマンドの前にIPアドレスを渡したいとします。

逆にping 1.1.1.11.1.1.1 ping

事前にありがとう

答え1

これは次の例で機能しますping

echo 1.1.1.1 | xargs ping

コマンドの前のパラメータ

答え2

これは少し面倒ですが、ほとんど動作しているようです。

cmd_handler() {
    eval "cmd_words=($BASH_COMMAND)"
    last_word="${cmd_words[@]: -1:1}"
    if [ "$last_word" = gnip ]
    then
        argcm1=$((${#cmd_words[@]}-1))
        ping "${cmd_words[@]:0:$argcm1}"
        return 1
    fi
}
shopt -s extdebug
trap cmd_handler debug

明らかに、最初の10行はという関数を定義しますcmd_handler。このtrap cmd_handler debugコマンドは、cmd_handler入力するすべてのコマンドに対して bash を呼び出す必要があることを指定します。たとえば、ユーザーが入力したコマンドは変数の関数に1.1.1.1 ping使用できます$BASH_COMMAND。これはスカラー文字列なので、cmd_words=($BASH_COMMAND)単語に分割します。これにより、仮想コマンドが生成されます。

ls -l This is "Super User".

6文字で区切られます。

  • ls
  • -l
  • This
  • is
  • "Super
  • User".

だから私たちはそれをevalシェルに引用符を解釈させるのに使います。この構成は以下を生成します。${array_name[@]:offset:length}lengthで始まる配列メンバーです。一つ${array_name[offset]}offset-1 は最後の要素を参照するので、名前が示すように、コマンドの最後の単語として評価されます。言った内容とは異なるようにスペースを含めてください。これがカスタムコマンドの名前である場合(テスト目的でそのように表現しました)、引数の数から1()を引いた値を計算し、最後の単語を除くすべてのコマンドを引数として実行します。一般的な解析では、このコマンドを処理しないようにシェルに指示します。:-gnipargcm1pingreturn 1

いくつかの欠陥と解決策が見つかりました。

  • 明らかにこれは処理できません1.1.1.1 gnip -n 4 -w 500
    • それはそれを処理します1.1.1.1 -n 4 -w 500 gnip
    • cmd_handler コマンドラインのすべての単語を調べて、カスタムコマンドの名前を見つけるように変更できます。
  • 1.1.1.1 gnip > ping.outcmd_handler最後の文が表示されるため、機能しませんping.out。あなたはそれを使用することができます

    • (1.1.1.1 gnip) > ping.outまたは
    • { 1.1.1.1 gnip;} > ping.out

    最初はサブシェルでコマンドを実行しますが、2番目はそうではありません。 2番目のフォームの後にスペースが必要で、{ 前にセミコロン(;)が必要であることを覚えておいてください}

  • 1.1.1.1 gnip | some other commandうまくいかず、なぜそれがうまくいかないのかわかりません。コマンドをプライマリシェルで実行したいかどうか、または別の形式を使用してこの問題を解決することで、この問題を解決できます。(1.1.1.1 gnip) > >(some other command){ 1.1.1.1 gnip;} > >(some other command)

私がまだ発見していない他の落とし穴があるかもしれません。

関連情報