Bir dosyaya bu komut dosyası kaç kez yürütüldüğünü yazan bir komut dosyası yazmam gerekiyor.
Bunu nasıl yapabilirim?
Bir dosyaya bu komut dosyası kaç kez yürütüldüğünü yazan bir komut dosyası yazmam gerekiyor.
Bunu nasıl yapabilirim?
Yanıtlar:
Sanırım countfileyürütme sayacını temsil eden tek bir sayı içeren tek bir dosyaya sahip olmak istiyorsunuz .
Bu sayacı bir kabuk değişkenine okuyabilirsiniz, $counterörneğin aşağıdaki satırlardan birini kullanarak:
read counter < countfilecounter=$(cat countfile)Basit tamsayı eklemeleri $(( EXPRESSION ))sözdizimi kullanılarak Bash'ın kendisinde yapılabilir . Sonra sadece bizim için sonuç geri yazma countfile:
echo "$(( counter + 1 ))" > countfile
Muhtemelen countfilehenüz mevcut olmayan vaka için komut dosyanızı korumalı ve sonra 1 değeriyle başlatılmış bir tane oluşturmalısınız.
Her şey şöyle görünebilir:
#!/bin/bash
if [[ -f countfile ]] ; then
read counter < countfile
else
counter=0
fi
echo "$(( counter + 1 ))" > countfile
$(…)Başka herhangi bir şeyden önce (özellikle önce >) yürütülecek garanti olup olmadığından emin değilim . Ancak, çoğunlukla $(cat countfile 2>/dev/null || echo 0), dosyanın mevcut olmaması durumunda makul bir varsayılan değer elde etmek için bu bölümü kullanıyorum . spongeGüvenli olmak için :-) ekleyebiliriz .
flockyarış koşullarını önlemek için bu sayma kodunun bir komutla sarılmasıyla geliştirilecektir . Bkz. Unix.stackexchange.com/a/409276
Betiğin bir günlük dosyası oluşturmasına izin verin, örneğin betiğinizin sonuna bir satır ekleyin:
echo "Script has been executed at $(date +\%Y-\%m-\%d) $(date +\%H-\%M-\%S)" >> ~/script.log
Bu şekilde, tarih ve saati sunma şeklinizi kendiniz biçimlendirebilirsiniz, ancak yalnızca tam bir tarih ve saatle gitmek istiyorsanız (ve HH:MM:SSsizin için kabul edilebilir bir biçimse) şunları da kullanabilirsiniz:
echo "Script has been executed at $(date +\%F-\%T)" >> ~/script.log
Sonra şunları yapabilirsiniz:
wc -l ~/script.log
Bu, yeni satır karakterlerini sayar ve günlük dosyasının içinde kaç satır olduğunu tahmin eder. Buna kadar yürütüldüğünde bile günlük dosyasının içinde görebilirsiniz. Gereksinimlerinize uyarlamak için, günlük kaydı için kullanılan yolları ve adları değiştirebilirsiniz. Ben sadece burada logfile kaydeder bir örnek yaptım ~.
Örneğin, betiğin bu sayımı betiğinizin sonuna eklediğiniz satıra eklemesini istiyorsunuz, betiğinizin başında böyle bir şey yapabilirsiniz:
count=$(( $(wc -l ~/script.log | awk '{print $1}') + 1 ))
# the next line can be simply skipped if you not want an output to std_out
echo "Script execution number: $count"
Ve betiğin sonundaki satırınızı, bu bilgileri bile içeren bir şeye değiştirin:
echo "Script has been executed $count times at $(date +\%F-\%T)" >> ~/script.log
Bu çözüm Byte Commander'ın cevabı ile aynı yaklaşımı kullanır, ancak kabuk aritmetiği veya diğer Bashizmlere dayanmaz.
exec 2>&3 2>/dev/null
read counter < counter.txt || counter=0
exec 3>&2 3>&-
expr "$counter" + 1 > counter.txt
Akış yönlendirmeleri
/dev/null( readsayaç dosyası beklenen şekilde eksikse komut girişinin sonraki yönlendirmesinde hata mesajını bastırmak için ),Ayrı bir sayaç dosyasının dezavantajları vardır:
Yani bu cevap ayrı bir sayaç dosyası ile ortadan kalkar ve sayımı bash betiğinin kendisine koyar!
flockiki kullanıcı aynı anda komut dosyasını çalıştırmak için kısa bir an için bu mümkün değil garantileri.#!/bin/bash
# NAME: run-count.sh
# PATH: $HOME/bin
# DESC: Written for AU Q&A: /ubuntu/988032/how-can-i-cause-a-script-to-log-in-a-separate-file-the-number-of-times-it-has-be
# DATE: Mar 16, 2018.
# This script run count: 0
# ======== FROM HERE DOWN CAN GO INTO FILE INCLUDED WITH SOURCE COMMAND =======
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
# This is useful boilerplate code for shell scripts. Put it at the top of
# the shell script you want to lock and it'll automatically lock itself on
# the first run. If the env var $FLOCKER is not set to the shell script
# that is being run, then execute flock and grab an exclusive non-blocking
# lock (using the script itself as the lock file) before re-execing itself
# with the right arguments. It also sets the FLOCKER env var to the right
# value so it doesn't run again.
# Read this script with entries separated newline " " into array
mapfile -t ScriptArr < "$0"
# Build search string that cannot be named
SearchStr="This script"
SearchStr=$SearchStr" run count: "
# Find our search string in array and increment count
for i in ${!ScriptArr[@]}; do
if [[ ${ScriptArr[i]} = *"$SearchStr"* ]]; then
OldCnt=$( echo ${ScriptArr[i]} | cut -d':' -f2 )
NewCnt=$(( $OldCnt + 1 ))
ScriptArr[i]=$SearchStr$NewCnt
break
fi
done
# Rewrite our script to disk with new run count
# BONUS: Date of script after writing will be last run time
printf "%s\n" "${ScriptArr[@]}" > "$0"
# ========= FROM HERE UP CAN GO INTO FILE INCLUDED WITH SOURCE COMMAND ========
# Now we return you to your original programming....
exit 0
Videonauth cevabı Benzer Burada bir günlük dosyası cevap yazdı: Bash komut / denetim izi korumak dosyaların oturum açmak için erişilebilir kök güçler ile kullanılmıştır her zaman günlüğe geditya nautilus.
Yakalama olsa gksukomut dosyası kullanmak yerine adlandırılır gsuve pkexecGUI sudo kullanma "modern" yolunu çağırıyor , bu yüzden söylendi.
Başka bir avantaj, sadece kök güçlerin her kullanılışında geditdeğil, düzenlenen dosya adını günlüğe kaydetmesidir. İşte kod.
~/bin/gsu:
#!/bin/bash
# Usage: gsu gedit file1 file2...
# -OR- gsu natuilus /dirname
# & is used to spawn process and get prompt back ASAP
# > /dev/null is used to send gtk warnings into dumpster
COMMAND="$1" # extract gedit or nautilus
pkexec "$COMMAND" "${@:2}"
log-file "${@:2}" gsu-log-file-for-"$COMMAND"
/usr/local/bin/log-file:
#! /bin/bash
# NAME: log-file
# PATH: /usr/local/bin
# DESC: Update audit trail/log file with passed parameters.
# CALL: log-file FileName LogFileName
# DATE: Created Nov 18, 2016.
# NOTE: Primarily called from ~/bin/gsu
ABSOLUTE_NAME=$(realpath "$1")
TIME_STAMP=$(date +"%D - %T")
LOG_FILE="$2"
# Does log file need to be created?
if [ ! -f "$LOG_FILE" ]; then
touch "$LOG_FILE"
echo "__Date__ - __Time__ - ______File Name______" >> "$LOG_FILE"
# MM/DD/YY - hh:mm:ss - "a/b/c/FileName"
fi
echo "$TIME_STAMP" - '"'"$ABSOLUTE_NAME"'"' >> "$LOG_FILE"
exit 0
gsu-log-file-for-geditBirkaç düzenlemeden sonra günlük dosyasının içeriği :
__Date__ - __Time__ - ______File Name______
11/18/16 - 19:07:54 - "/etc/default/grub"
11/18/16 - 19:08:34 - "/home/rick/bin/gsu"
11/18/16 - 19:09:26 - "/home/rick/bin/gsu"
echo $(( $(cat countfile 2>/dev/null || echo 0) + 1 )) > countfile