でsed -e
を使用して設定ファイルのいくつかのパラメータを更新し、それを| tee
にパイプすると、これがランダムに壊れてファイルが無効(サイズ0)。要約するとteeを使ってファイルをランダムに更新すると、linux bashスクリプト
、このコードは、パラメータを更新するために使用されます。
# based on the provided linenumber, add some comments, add the new value, delete old line
sed -e "$lineNr a # comments" -e "$lineNr a $newValue" -e "$lineNr d" $myFile | sudo tee $myFile
私はこのupdateコマンドを100回呼び出すスクリプトを設定します。 OSXでの共有ディレクトリ上のUbuntuのVM(Parallels Desktopの)で
- この 動作は、この動作は40までに発生 UbuntuのパーティションにUbuntuのVM(Parallels Desktopの)で50回
- までに発生なぜこれが起こっている(UbuntuのとIntelNUC)ネイティブシステム・オン回
- この動作は15回
まで発生は、誰かが説明できますか?
ここでは、実験を実行できる完全に機能的なスクリプトもあります。
#!/bin/bash
# main function at bottom
#====================
#===HELPER METHOD====
#====================
# This method updates parameters with a new value. The replacement is performed linewise.
doUpdateParameterInFile()
{
local valueOfInterest="$1"
local newValue="$2"
local filePath="$3"
# stores all matching linenumbers
local listOfLines=""
# stores the linenumber which is going to be replaced
local lineToReplace=""
# find value of interest in all non-commented lines and store related lineNumber
lineToReplace=$(grep -nr "^[^#]*$valueOfInterest" $filePath | sed -n 's/^\([0-9]*\)[:].*/\1/p')
# Update parameters
# replace the matching line with the desired value
oldValue=$(sed -n "$lineToReplace p" $filePath)
sed -e "$lineToReplace a # $(date '+%Y-%m-%d %H:%M:%S'): replaced: $oldValue with: $newValue" -e "$lineToReplace a $newValue" -e "$lineToReplace d" $filePath | sudo tee $filePath >/dev/null
# Sanity check to make sure file did not get corrupted by updating parameters
if [[ ! -s $filePath ]] ; then
echo "[ERROR]: While updating file it turned invalid."
return 31
fi
}
#===============================
#=== Actual Update Function ====
#===============================
main_script()
{
echo -n "Update Parameter1 ..."
doUpdateParameterInFile "Parameter1" "Parameter1 YES" "config.txt"
if [[ "$?" == "0" ]] ; then echo "[ OK ]" ; else echo "[FAIL]"; return 33 ; fi
echo -n "Update Parameter2 ..."
doUpdateParameterInFile "Parameter2" "Parameter2=90" "config.txt"
if [[ "$?" == "0" ]] ; then echo "[ OK ]" ; else echo "[FAIL]"; return 34 ; fi
echo -n "Update Parameter3 ..."
doUpdateParameterInFile "Parameter3" "Parameter3 YES" "config.txt"
if [[ "$?" == "0" ]] ; then echo "[ OK ]" ; else echo "[FAIL]"; return 35 ; fi
}
#=================
#=== Main Loop ===
#=================
#generate file config.txt
printf "# Configfile with 3 Parameters\n#[Parameter1]\n#only takes YES or NO\nParameter1 NO \n\n#[Parameter2]\n#Parameter2 takes numbers\nParameter2 = 100 \n\n#[Parameter3]\n#Parameter3 takes YES or NO \nParameter3 YES\n" > config.txt
cp config.txt config.txt.bkup
# Start the experiment and let it run 100 times
cnt=0
failSum=0
while [[ $cnt != "100" ]] ; do
echo "==========run: $cnt; fails: $failSum======="
main_script
if [[ $? != "0" ]] ; then cp config.txt.bkup config.txt ; failSum=$(($failSum+1)) ; fi
cnt=$((cnt+1))
sleep 0.5
done
よろしく DonPromillo
のようなあなたの
tee
アプローチを使うのか?また、 'sed'を使ってファイルを処理するのとまったく同じ時にファイルを上書きするために' tee'を使用しているので、競合状態が最も発生しているようです。 'tee'が' sed'を得る前にファイルを切り詰めると '0'長さのファイルが得られます。あなたの 'sed'がそれをサポートしていれば、その場所でファイルを修正することができます。そうでなければ、出力を一時ファイルに書き込んで元の名前に移動してください。 –パイプの両側は非同期です。 'tee'が上書きする前に' sed'が 'myFile'の内容を完全に消費していることを保証することはできません。 – chepner
@EricRenoufと@chepnerありがとうございました。私が「ティー」を使っていた理由は、基本的にはパイピングの好奇心です。 – DonPromillo