Raspberry Piスパイカムバグを作成しようとしています。個々のプロセスごとに作成された新しいファイルが表示されるようにしようとしています
NOW=`date '+%F_%H:%M:%S'`;
良い結果。ただし、ファイルを更新せずに同じ問題でも$NOW
時間を更新するには、エコーが必要です。/home/pi/.bashrc
. ~/.bashrc
私が見つけたこのフォーラムでは効果があります:
#! /bin/bash
NOW=`date '+%F_%H:%M:%S'`;
filename="/home/pi/gets/$NOW.jpg"
raspistill -n -v -t 500 -o $NOW.jpg;
echo $filename;
raspistilの出力の前に引用符で囲まれているので、それがどのように機能するのかわかりません。
みんなありがとうございます! ! !
答え1
するとき
NOW=`date '+%F_%H:%M:%S'`
またはより現代的な構文を使用して
NOW=$( date '+%F_%H:%M:%S' )
NOW
この変数は、この行が実行されるとコマンドの出力に設定されます。date
でこれを行うと、~/.bashrc
現在の$NOW
インタラクティブシェルセッションの開始時期を示すタイムスタンプが表示されます。
以下を使用して変数値を設定することもできます。
printf -v NOW '%(%F_%H:%M:%S)T' -1
bash
バージョン4.2以降を使用している場合。これにより、呼び出さずにタイムスタンプが変数に直接印刷されますdate
。
表示されるスクリプトでは、NOW
スクリプトの実行中に変数が設定されます(必要に応じて)。
割り当てるとき
filename="/home/pi/gets/$NOW.jpg"
実行後、シェルは文字列の変数を拡張します。二重引用符で囲んでも、これが行われます。 アポストロフィシェルが組み込み変数を拡張するのを防ぎます(これはいいえこの場合は何をしたいですか?)
filename
呼び出しで実際に変数を使用していないようなので、最後に出力したいraspistill
場合以外は、その値を設定する理由がわかりません。echo
コードの残りの部分では、$NOW
変数拡張(および$filename
)を二重引用符で囲む必要があります。これを行わずに、後で定義にNOW
スペースまたはワイルドカード(ファイル名ワイルドカードパターン)が含まれるように定義を変更すると、使用するコマンドが$NOW
そのコマンドラインを正しく解析できないことがあります。
たとえば、比較してみてください。
string="hello * there"
printf 'the string is "%s"\n' $string
そして
string="hello * there"
printf 'the string is "%s"\n' "$string"
関連事項:
コマンド置換のバックティック関連:* shシェルではバックティック(「cmd」など)は使用されなくなりましたか?
参照変数の拡張について:bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスクそしてスペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?
答え2
この答えは実用的なアドバイスです。
:
ファイルの命名などの文字を使用しないでください。英数字以外の文字を使用する前に、将来のスクリプトまたはコマンドラインの1行コードを台無しにすることができるかどうかを確認してください。代わりに、ダッシュやアンダースコアを使用したり、区切り文字を使用せずに要素を単純に圧縮します。あなたの質問によると、を使用しているように見えるので、最新バージョンのシェルには、シェル
bash
独自のコマンドを含むprintf
日付仕様出力のデフォルトバージョンが含まれていることに注意してください。次のように使用してください。printf "%(%F_%H%M%S)T"
または
NOW=$(printf "%(%F_%H%M%S)T")
でも
printf -v NOW "%(%F_%H%M%S)T"
(これにより、追加プロセスがフォークするのを防ぐことができます)
bash
印刷日付仕様バージョンには、他の場合には存在しない2つの機能という追加の利点があります。 「-1」は現在時刻を示し、-2はシェルが呼び出された時刻を示します。引数が指定されていない場合、変換は次のように動作します。 -1が与えられた場合。」例えば、printf -v THEN "%(%F_%H%M%S)T" -2
答え3
Bash 5基準:エポック(1970-01-01 00:00:00)以降の秒数が要件に適合する場合は、事前定義された2つの変数から対応するタイムスタンプを取得できます。
# Seconds since epoch
echo ${EPOCHSECONDS}
# Seconds with microsecond precision since epoch
echo ${EPOCHREALTIME}
# Microseconds since epoch
echo ${EPOCHREALTIME/./}
# Miliseconds since epoch
echo $(( ${EPOCHREALTIME/./} / 1000 ))
答え4
私は何度も更新されたファイルを踏むのを防ぐために、bashで実行されたときにスクリプトが実際に時間を更新するようにし(例えば、正しい)、変数に単に「割り当て」する方法を探しています。 Perlではこれが問題にならないことは確かですが、かなり長い時間がかかりました。
user1404316の答えはRHELのbash 4.2では機能しません。
bash 4.2でこの問題を解決した方法は次のとおりです。
#!/bin/bash
now=$(printf "%(%F_%H%M%S)T")
echo printf: ${now}
sleep 1
echo printf after 1: ${now}
# Tried backticks here too :(
then="$(date +%s)"
# This is your now date
now() { date +%s; }
# This is how you use it
filename="something.$(now)"
echo "now ${filename}"
filename="something.${then}"
echo "then ${filename}"
sleep 1
filename2="something.$(now)"
echo "now ${filename2}"
filename2="something.${then}"
echo "then ${filename2}"
そして出力:
printf: 1969-12-31_190000
printf after 1: 1969-12-31_190000
now something.1588791459
then something.1588791459
now something.1588791460
then something.1588791459
これが誰かに役立つことを願っています:)
- ある程度クレジットを与えなければなりません不明なユーザー@askubuntu.com なぜなら、正しい解決策を見つけようとしてコードを確認したからです。