web-dev-qa-db-ja.com

生成された空の文字列をコマンドライン引数として渡す

私は以下を行います:

$ ./input ""

出力:

argc 2
argv[1][0] 0

しかし、プログラムベースの方法で(いくつかの)空の引用符を渡したい場合:

$ python -c 'print "\"\""'
""

./input $(python -c 'print "\"\""')

与える:

argc 2
argv[1][0] 22 - (22 hex value for ")

それで、どうすれば次のようなものを生成できますか?

$ ./input "" "" "" ""

例1と同じ結果を取得しますか?

6
Alex Hoppus

コマンドライン全体をプログラムで生成し、コピーして貼り付けるか、evalで実行することができます。例:

$ Perl -e 'printf "./args.sh %s\n", q/"" / x 10' 
./args.sh "" "" "" "" "" "" "" "" "" "" 

$ eval "$(Perl -e 'printf "./args.sh %s\n", q/"" / x 100')"
$#: 100
$1: ><

q/"" /は、Perlが文字列を引用する方法の1つであり、x 100それを100コピー作成し、それらを連結します。)

evalは、引数をシェルコマンドとして処理し、すべての引用処理と展開を実行します。つまり、入力が信頼できないソースからのものである場合は、脆弱性を防ぐために評価されたコードを生成する際に注意する必要があります。

空の引数変数の数が必要な場合、それは問題なく実行できるはずです(少なくとも、Perlのxの2番目のオペランドが、オペランドを整数に変換するため、誤用される可能性があることを思いつきません)。 :

$ n=33
$ eval "$(Perl -e 'printf "./args.sh %s\n", q/"" / x $ARGV[0]' "$n")"
$#: 33
$1: ><
4
ilkkachu

しかし、実際には何を渡したいですか?空の引用符または空の文字列?どちらも有効な引数であり、この単純なbashスクリプトはこれを説明するのに役立ちます。

#!/bin/bash

printf "Argument count: %s.\n" "${#@}"

渡された引数の数を出力するだけです。簡潔にするため、これをsと呼びます。

$ ./s a
Argument count: 1.
$ ./s a b
Argument count: 2.
$ ./s a b ""
Argument count: 3.
$ ./s a b "" ""
Argument count: 4.
$ ./s a b "" "" \"\"
Argument count: 5.

ご覧のとおり、空の文字列は単なる空の文字列です-引用符は解析時に削除されます-そして、それらはまだ有効な引数です。シェルはそれらをコマンドにフィードします。だが ""も渡すことができます。空の文字列ではありません。 2つの文字が含まれています。

内部では、Cの場合、文字列はNUL(\0)終了し、それらを表すために引用符は必要ありません。

2
user147505