コマンドに絶対パスオプションを追加する

コマンドに絶対パスオプションを追加する

シェルコマンド(「oldcommand」と呼びます)が与えられた場合、新しい「-location」オプションがあることを除いて、oldcommandと同じように動作する単純なシェルスクリプトnewcommand.shはありますか?

  newcommand -location path -nonfileoption1 x1 -fileoption2 x2 -fileoption3 x3  -nonfileoption4 x4

実行されます

 oldcommand  -nonfileoption1 x1 -fileoption2 path/x2 -fileoption3 path/x3  -nonfileoption4 x4

答え1

最初に1つのオプションにのみ興味があれば、これはほんの数行のスクリプトにすぎません。どこからでもオプションを解析して渡すには、数行のoldcommandコードが必要で、どのオプションに値があり、どのオプションに値がないかを知る必要があります。

~のためシンプルケース、

#!/bin/sh
[ "$#" -gt 2 && "x$1" = "x-location" ] && cd $2 && shift 2 && exec oldcommand "$@"
newcommand "$@"

複雑な場合は、これを実行できるように聞こえますgetopt(移植可能ではありません)。追加資料:

OPとの議論に基づいて問題を単純化するために使用できるパターンは次のとおりです。 "--fileopt"で始まるオプションには、位置オプションの値を前に追加する必要があります。したがって(代わりに実際のエラーチェックはありません。本物パス名に含まれる特殊文字の処理:

#!/bin/sh
PREP=
if [ "$#" -gt 2 ]
then
    PREP="$2/"
    shift 2
    ARGS=
    while [ "$#" != 0 ]
    do
        case "x$1" in
        (x-fileopt*)
            ARGS="$ARGS $1 ${PREP}$2"
            shift 2
            ;;
        (*)
            ARGS="$ARGS $1"
            shift 1
        esac
    done
    oldcommand $ARGS
else
    oldcommand "$@"
fi

答え2

これは匂いが似ています。XYの問題oldcommandすべての相対ファイル名を他のディレクトリと相対的なものとして扱うには、現在のディレクトリを変更してください。

(cd path && oldcommand  -nonfileoption1 x1 -fileoption2 x2 -fileoption3 x3  -nonfileoption4 x4)

角かっこは、ディレクトリの変更がローカルで行われることを保証します。次のコマンドは元のディレクトリで実行されます。

スクリプトでパッケージ化するには:

#!/bin/sh
cd "$1" && shift && "$@"

使用法:

run-in path oldcommand  -nonfileoption1 x1 -fileoption2 x2 -fileoption3 x3  -nonfileoption4 x4

ただし、コマンドラインを使用する場合は、一時ディレクトリを変更する方が便利です。より多くの入力が必要ですが、すぐにファイル名を完成させることができます。 (ラッパースクリプトメソッドにアクションを実行させることはできますが、run-inスクリプトの完了関数を定義する必要があります。)

cd path
oldcommand  -nonfileoption1 x1 -fileoption2 x2 -fileoption3 x3  -nonfileoption4 x4
cd -

または

pushd path
oldcommand  -nonfileoption1 x1 -fileoption2 x2 -fileoption3 x3  -nonfileoption4 x4
popd

要求されたものとは異なり、pathコマンドラインに渡されたファイル名だけでなく、oldcommand内部的に使用されるすべての相対ファイル名も、相対的なすべてのファイル名にします。これは、oldcommand他のディレクトリ自体にも変更されないと仮定します。多くのコマンドが両方の仮定を満足しています。

答え3

opt()
    case ${1##*:*}:${#2} in
    (--:*) ! x=$((x-2))  ;;
    (-nonfileoption:[!0]*) p=;;
    (-fileoption:[!0]*)    p=\$2/;;
    (*:0)  eval $"{$x"':?Bad option::arg: "$1::$2"}';;
    (*)    eval $"{$((x-1))"':?Bad option: "$1"}'
    esac

[ " -location" = " $1" ] && x=2 parm= &&
while  [ "$#" -ge "$((x+=2))" ]
do     eval 'opt  "${'"$((x-1))"'}" "${'"$x}\"" ||
          until [ "$x" -eq "$#" ] && break 2
          do    parm=$parm' "${'$((x+=1))}\"
          done
       parm=$parm' "${'$((x-1))'}"  "'$p\${$x}\"
done&& eval "set -- $parm"

関連情報