16

/proc/cmdline を解析するほとんどのスクリプトは、それを単語に分割してから、case ステートメントで引数を除外します。例:

CMDLINE="quiet union=aufs wlan=FOO"
for x in $CMDLINE
do
»···case $x in
»···»···wlan=*)
»···»···echo "${x//wlan=}"
»···»···;;
»···esac
done

問題は、WLAN ESSID にスペースが含まれている場合です。for ループがスペースで分割されるため、ユーザーはwlan='FOO BAR' (シェル変数のように) を設定し、上記のコードで予期しない結果が得られることを期待しています。'FOO

/proc/cmdlineシェルスクリプトから解析して、ほとんど評価するのに足りないより良い方法はありますか?

または、引用のトリックはありますか?私はおそらくユーザーにスペースを引用して次のようにデコードするように頼むことができると考えていました: /bin/busybox httpd -d "FOO%20BAR". それともそれは悪い解決策ですか?

4

8 に答える 8

4

最も一般的に\0ctalは、スペースが受け入れられない場合にエスケープシーケンスが使用されます。

Bashでは、printfそれらをエスケープ解除するために使用できます。

CMDLINE='quiet union=aufs wlan=FOO\040BAR'
for x in $CMDLINE; do
    [[ $x = wlan=* ]] || continue
   printf '%b\n' "${x#wlan=}"
done
于 2009-06-17T17:47:30.540 に答える
2

これらの引数を $cmdline_union や $cmdline_wlan などの変数に変換する、bash を使用して次のようなことを行うことができます。

bash -c "for i in $(cat /proc/cmdline); do printf \"cmdline_%q\n\" \"\$i\"; done" | grep = > /tmp/cmdline.sh
. /tmp/cmdline.sh

次に、通常のシェルと同じように、引用やエスケープを行います。

于 2011-06-02T02:59:37.970 に答える
1

優雅に:

$ f() { echo $1 - $3 - $2 - $4 
> }
$ a="quiet union=aufs wlan=FOO"
$ f $a
quiet - wlan=FOO - union=aufs -

関数を定義し、引用符なしで$CMDLINE を関数の引数として指定できます。次に、シェルの解析メカニズムを呼び出します。これが動作するシェルでこれをテストする必要があることに注意してください--zshは引用符で面白いことをします;-)。

次に、シェルのように引用を行うようにユーザーに指示できます。

#!/bin/posh
CMDLINE="quiet union=aufs wlan=FOO"
f() {
        while test x"$1" != x 
        do      
                case $1 in
                        union=*)        echo ${1##union=}; shift;;
                        *)              shift;; 
                esac    
        done    
}       
f $CMDLINE

(posh - ポリシーに準拠した通常のシェル、標準の POSIX を超える機能が取り除かれたシェル)

于 2009-06-17T11:00:44.110 に答える
-1

ここで awk を使用する良い方法を 見つけましたが、残念ながら二重引用符でのみ機能します。

# Replace spaces outside double quotes with newlines
args=`cat /proc/cmdline | tr -d '\n' | awk 'BEGIN {RS="\"";ORS="\"" }{if (NR%2==1){gsub(/ /,"\n",$0);print $0} else {print $0}}'`

IFS='                                                                           
'                                                                               
for line in $args; do                                                           
     key=${line%%=*}                                                            
     value=${line#*=}                                                           

     value=`echo $value | sed -e 's/^"//' -e 's/"$//'`                          

     printf "%20s = %s\n" "$key" "$value"                                       

done
于 2013-04-26T09:21:23.443 に答える