2016-07-25 16 views
1

私はJavaクラスを呼び出すために使用するbashスクリプトを持っています。このJavaクラスに2つの引数を渡します。最初の引数($ 1)は、渡す文字列であり、誰かの名前が入っています。 2番目の引数($ 2)は前の月で、2桁の数字です(これもユーザーが渡します)。bashスクリプト内で引数を渡す

だから、Javaのクラスは、このように呼ばれている:

java -DCONFIG_DIR=... com.example.myapp.grades.gradingProcess $1 $2 

しかし、今、私は、ユーザーが第二引数に渡したくない、その代わりに、私はスクリプトが月に決定したいと思います。
このようなことをすることはできますか?

 month=`date +'%m' -d 'last month'` 

java -DCONFIG_DIR=... com.example.myapp.grades.gradingProcess $1 $month 

そして、私は私のスクリプトを実行すると、それはこのようなものになるだろう:私はすでにスクリプト内でそれをやっているので、「ジョン ないが、2桁の月を渡し./myscript.sh ?

それは正しい方法ではありませんか? 申し訳ありませんが、これは基本的な質問のようですが、私はまだbashスクリプトに慣れようとしています。

ありがとうございますか?

+8

はい、動作するはずです。 1つの提案:人の名前にスペースがある場合は、 '$ 1'を二重引用符で囲み、単一のトークンとして渡すようにします。 (ユーザーは二重引用符も使用する必要があります) –

+1

@JuanTomas - スペースが必要な場合*だけでなく、あなたがそれを必要としないときでも適切な引用をすると、あなたの期待が間違っていたときにバグを避けることができます。 (私は '[0-9a-f] {24}'にマッチするファイル名のみを含むと予想される変数拡張を引用しないようにした後に、大量のデータ損失イベントを実際に見た - バッファオーバーフローは、空白で囲まれたアスタリスクを名前に置き、作成が苦手なスクリプトがそのファイルを削除しようとしましたが、惨事が続きました)。 –

+0

@JuanTomasなので、$ monthを引用符で囲む必要はありません。 また、私は1つの単語の名前(スペースなし)だけを渡すという事実を知っていますが、頭のためにありがとう!ちゃんと覚えておきますよ。 – user3266259

答えて

2

シェルでデフォルト値を指定する方法を探している場合は、そのための演算子があります。 $2の値があった場合

month=${2-$(date -d 'last month' +%m)} 

java -stuff "$1" "$month" 

さて、monthはそれに設定されます。それ以外の場合は、デフォルトが使用されます。 ${variable-value}という表記はvariableの値を提供し、設定されていない場合はvalueの値を提供します。 (variableが同様に設定されていますが、空にされている場合valueを生成${variable:-value}もあります。)

それを壊すために変数を使用すると、おそらく、読みやすさのためのより良いですが(これは、でも、javaコマンドラインにインライン化することができます。

java -stuff "$1" "${2-$(date -d 'last month' +%m)}" 

あなたは基本的に常に二重引用符でユーザー提供の変数を入れても、どのようにお知らせ。)

+0

月= $ {2 - $(日付-d '先月' +%m)} なぜこの変数に2が必要ですか? – user3266259

+0

'$ 2'が設定されている場合、' month = $ 2'です。 '$ 2'が設定されていない場合、' month = $(date -d '先月' +%m) '。私は答えでこれを説明しようとしました。それは明確ではないのですか? – tripleee

+0

ああ、ちょうどそれを見た。ありがとうございました。 – user3266259

0

タイムゾーン、先行ゼロ、およびbashではなくJavaを活用していることについて、少し考えてみましょう。

タイムゾーン

現在の月を特定するには、現在の日付が必要です。現在の日付を決定するには、タイムゾーンが必要です。

任意の瞬間について、日付は世界中で異なります。例えば、モントリオールではまだ "昨日"の間、パリの真夜中から数分後に新しい日があります。

タイムゾーンを指定しない場合は、現在の既定のタイムゾーンが暗黙的に適用されます。デフォルトはいつでも変更できることに注意してください。また、デフォルトでは、コードは直接コントロール外の外部性に依存しています。それは結果が変わることを意味します。

だから、月の終わり/頃には、再生中のタイムゾーンを誤った月番号にすることができます。ゼロをリードする

は、使用している%mは2桁の数字を生成するJava

に進を意味することができます。一桁の月の数字は先行ゼロを持ちます。例:09

Javaの状況によっては、先行ゼロの数値は10進数(基数10)ではなくoctal number(基数8)と解釈されることに注意してください。

みましょうJavaは仕事

私はそれがJavaクラスが前月決定の仕事をやらせるために、より理にかなって提案を行います。 bash行は、もしあれば、月ではなく、希望/予想される時間帯を渡す必要があります。

ZoneId zoneId = ZoneId.of("America/Montreal") ; 
int previousMonthNumber = LocalDate.now(zoneId).minusMonths(1).getMonthValue() ; 

ヒント:Javaでは、より良いMonth列挙型ではなく、単なる整数からオブジェクトを使用します。コードの自己文書化、型安全、有効な値の保証を行います。

Month month = LocalDate.now(zoneId).minusMonths(1).getMonth() ; 
+1

'date'コマンドのタイムゾーンを指定するのは簡単です。コマンドラインで 'TZ'を設定するだけです。 (例: 'TZ = America/Lima date +% - m -d'last month'')。 – rici

+0

"いつでもデフォルトが変わる"と言っても過言ではありません。シェルを実行している場合、環境はシェルが初期化される前に作成され、シェルが終了するまで置かれたままになります。その間に管理者がグローバルなデフォルト設定を変更すると、新しいシェルを起動したときにのみ通知されます。 – tripleee

+0

私の指摘は、デフォルトのタイムゾーンに暗黙のうちに依存するという2つのリスクがあります。(a)コントロール外の外部性(結果が完全に変わると過度に劇的ではない)、(b)月を決定することで一般的にタイムゾーンを知りません。 –

関連する問題