質問: 引用符付きの問題のあるビルドスクリプト こんにちは私はこれらのコマンドを実行するビルドスクリプトを作成しようとしています:cd libiconv ../../src/libiconv/configure --prefix=/home/ruben/mingw64/build/gcc-libs \ --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 \ cflags="-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer" lflags="-flto -fwhopr=2" make -j3 -s make -s install cd .. 次のようになります。#!/bin/sh host=x86_64-w64-mingw32 target=x86_64-w64-mingw32 build=x86_64-w64_mingw32 # options build_cores=2 #used as argument for "make -j#" # directories: src_dir contains full source package. gcc_libs_dir=$build_dir/gcc-libs # optimized for my system. build_cflags="\"-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer\"" build_lflags="\"-flto -fwhopr="${build_cores}"\"" config_opts="--prefix="${prefix}" --host="${host}" --build="${build}" cflags="${build_cflags}" lflags="${build_lflags} makeopts="-s -j"${build_cores} # libiconv cd libiconv echo "configuring libiconv: "${config_opts} ../../src/libiconv/configure "${config_opts}" > configure.log || exit 1 echo "building libiconv" make $makeopts > build.log || exit 1 echo "installing libiconv" make -s install > install.log || exit 1 cd .. 重要なのは、echoコマンドは私が望む正確なconfigureコマンドを示していますが、configureを実行すると、それは正しくありません。 configureが引数として-flto(引用符で囲まれています!!)を使用しようとすると、cflags=-mtunecore2の後、何かがひどく間違っています。私は何が間違っているのですか?ありがとう!ps:私はmsysを実行していますが、real * nix ..ではありません。
回答: ここには純粋にunixoidシェルの問題がいくつかありますが、msysが余分な問題を追加していないことを願っています。複数レベルの引用を行うのは難しい場合があります。私は通常、可能であればそれらを避けることを好みます。以下の変更では、_$@_パラメーターを使用して、空白が埋め込まれる引数を格納および取得します。空白が埋め込まれたこのような引数のリストが複数必要で、シェルに配列パラメーターがある場合は、それらを使用できます(_$@_は1つしかないため)。_# assume build_cores is simple enough that it will not need extra quoting later... build_cflags='-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer' build_lflags="-flto -fwhopr=$build_cores" set -- --prefix="$prefix" --host="$host" --build="$build" cflags="$build_cflags" lflags="$build_lflags" makeopts="-s -j$build_cores" # libiconv cd libiconv echo "configuring libiconv: $@" ../../src/libiconv/configure "$@" > configure.log || exit 1 _ 指定された要件では、この単一レベルの保護だけで解決できますが、複数レベルの引用が必要な場合(たとえば、_build_cores_に空白が含まれている場合は、複数レベルの引用を処理します。 makeopts/_build_lflags_での1レベルの引用、および_config_opts_での2レベルの引用。その場合、printfを_%q_およびevalとともに使用することに頼るかもしれません。 _%q_形式指定子は、すべてではありませんが、ほとんどのシェルで使用できます(ksh、bash、zsh)。後で正しく評価できるように、値を引用します。_build_cflags='-mtune=core2 -flto -fomit-frame-pointer -momit-leaf-frame-pointer' build_lflags=$(printf '%s-flto -fwhopr=%q' '' "$build_cores") config_opts=$(printf \ '%s--prefix=%q --host=%q --build=%q cflags=%q lflags=%q' '' \ "$prefix" "$host" "$build" "$build_cflags" "$build_lflags") makeopts=$(printf '%s-s -j%q' '' "$build_cores") # libiconv cd libiconv echo "configuring libiconv:" "$config_opts" eval ../../src/libiconv/configure "$config_opts" echo "building libiconv" eval make "$makeopts" > build.log || exit 1 _この特定のケースでは、configureからlflagsを取得するものはすべて、シェルが生成した引用値を「読み取る」方法を知っていることに注意する必要があります。スクリプトがシェル言語で記述されている場合、これは問題になる可能性があります。シェル言語では、_%q_が、システムのデフォルトシェル(つまり、_/bin/sh_)が理解できない構造を生成します(例:ksh =は時々_$'blah'_構造を生成しますが、一部のシェルはそれらを解析する方法を知りません)。