次
のように、開いて閉じる機能を持つシェルスクリプトを作成したいと思います。
echo -e "Activated!"
第二:
echo -e "Deactivated!"
これを行う方法はありますか?
答え1
これは、アクティブ化の現在の状態を保存する必要があることを意味します。
最も簡単な方法は、「on」または「active」のいずれかの状態のファイルを作成し、別の状態(「off」または「deactivated」)に入ったときにファイルを削除することです。
完了を使用して空のファイルを作成しtouch filename
、完了を使用してファイルが存在するかどうかをテストしますif [ -e filename ]; then ...; fi
。 rm filename
.
以下に、変数の値をファイルに保存して、この状態に関するいくつかの情報を保存するオプションを示します。この場合、ステータスはスクリプトが実行されるたびに変更される永続ファイル(スクリプトが呼び出されるたびに作成または削除されるファイルではありません)によって渡されます。
以下を使用するとしますbash
。
#!/bin/bash
statefile=$HOME/.script.state
if [ -f "$statefile" ]; then
. "$statefile"
fi
case $state in
on) state=off ;;
*) state=on
esac
printf 'Current state is "%s"\n' "$state"
declare -p state >"$statefile"
テスト:
$ bash script.sh
Current state is "on"
$ bash script.sh
Current state is "off"
$ bash script.sh
Current state is "on"
$ bash script.sh
Current state is "off"
スクリプトは、各実行の終わりにinを介して変数を保存し、最初にファイルをインポートし(存在する場合)そこstate
から変数を$HOME/.script.state
読み込みますdeclare -p state
。bash
ファイルは次のように見えます。
declare -- state="off"
declare -p state
これは$state
if is the stringの出力ですoff
。
これにより、上記の/bin/sh
スクリプトは次のように書くことができます。
#!/bin/bash
statefile=$HOME/.script.state
if [ -f "$statefile" ]; then
read state <"$statefile"
fi
case $state in
on) state=off ;;
*) state=on
esac
printf 'Current state is "%s"\n' "$state"
printf '%s\n' "$state" >"$statefile"
...ステータスの読み取りと書き込みをandに置き換えると、ステータスread
文字printf
列自体のみがステータスファイルに保存されます。
答え2
実行されるたびに状態を自動的に反転したい場合は、値を反転するのに役立つ「論理的に否定的な」数値操作を利用することもできます。つまり、ゼロの論理的否定は1であり、その逆も同様です。
POSIXシェルは、次のように最も一般的な数値およびビット操作を実行できます。算術拡張とバッシュは短くない、また提供しますソート0または1(およびそれ以上)などの整数でインデックスを作成できます。
実際:
(
# our persistent file to save state into
file=./state
# array of two states, "off" is the first so that it will be 0, and "on" will be 1
states=(off on)
# import what's been saved in our state file, if present
[ -f "$file" ] && source "$file"
# within the arithmetic expansion syntax,
# we compute new state as the logical negation (the `!` operator) of the current state
state=$(( !(state) ))
printf 'state=%d\n' $state > "$file" # save new state to persistent file
# print current state from the array using the numeric state as index
printf 'currently %s\n' "${states[state]}"
)
厳密なPOSIXシェルでは、配列が欠落している問題を解決する必要があるため、もう少し複雑です。
(
file=./state
# here we use a simple string instead of an array
states='off on'
[ -f "$file" ] && . "$file" # the `source` command POSIXly is just `.`
state=$(( !(state) ))
printf 'state=%d\n' $state > "$file"
# here we use the `cut` tool to select the piece of string based on numeric state
echo -n 'currently '; printf '%s\n' "$states" | cut -d ' ' -f $((state+1))
)