BASHの変数として現在の時刻/日付とスクリプトを使用してプログラムを停止する

BASHの変数として現在の時刻/日付とスクリプトを使用してプログラムを停止する

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"

関連事項:

答え2

この答えは実用的なアドバイスです。

  1. :ファイルの命名などの文字を使用しないでください。英数字以外の文字を使用する前に、将来のスクリプトまたはコマンドラインの1行コードを台無しにすることができるかどうかを確認してください。代わりに、ダッシュやアンダースコアを使用したり、区切り文字を使用せずに要素を単純に圧縮します。

  2. あなたの質問によると、を使用しているように見えるので、最新バージョンのシェルには、シェルbash独自のコマンドを含むprintf日付仕様出力のデフォルトバージョンが含まれていることに注意してください。次のように使用してください。

    printf "%(%F_%H%M%S)T"
    

    または

    NOW=$(printf "%(%F_%H%M%S)T")
    

    でも

    printf -v NOW "%(%F_%H%M%S)T"
    

    (これにより、追加プロセスがフォークするのを防ぐことができます)

  3. 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

これが誰かに役立つことを願っています:)

  1. ある程度クレジットを与えなければなりません不明なユーザー@askubuntu.com なぜなら、正しい解決策を見つけようとしてコードを確認したからです。

関連情報