Я предполагаю, что вы хотите иметь один файл countfile, который содержит только одно число, представляющее счетчик выполнения.
Вы можете прочитать этот счетчик в переменной оболочки $counter, например. используя одну из следующих строк:
read counter < countfile
counter=$(cat countfile)
Простые целочисленные дополнения могут быть сделаны в Bash с использованием синтаксиса $(( EXPRESSION )). Затем просто напишите результат на наш countfile:
echo "$(( counter + 1 ))" > countfile
Вероятно, вы также можете защитить свой скрипт в случае, когда countfile еще не существует, и создать один инициализированный значением 1, затем .
Все это может выглядеть так:
#!/bin/bash
if [[ -f countfile ]] ; then
read counter < countfile
else
counter=0
fi
echo "$(( counter + 1 ))" > countfile
Я предполагаю, что вы хотите иметь один файл countfile, который содержит только одно число, представляющее счетчик выполнения.
Вы можете прочитать этот счетчик в переменной оболочки $counter, например. используя одну из следующих строк:
read counter < countfile
counter=$(cat countfile)
Простые целочисленные дополнения могут быть сделаны в Bash с использованием синтаксиса $(( EXPRESSION )). Затем просто напишите результат на наш countfile:
echo "$(( counter + 1 ))" > countfile
Вероятно, вы также можете защитить свой скрипт в случае, когда countfile еще не существует, и создать один инициализированный значением 1, затем .
Все это может выглядеть так:
#!/bin/bash
if [[ -f countfile ]] ; then
read counter < countfile
else
counter=0
fi
echo "$(( counter + 1 ))" > countfile
Я предполагаю, что вы хотите иметь один файл countfile, который содержит только одно число, представляющее счетчик выполнения.
Вы можете прочитать этот счетчик в переменной оболочки $counter, например. используя одну из следующих строк:
read counter < countfile
counter=$(cat countfile)
Простые целочисленные дополнения могут быть сделаны в Bash с использованием синтаксиса $(( EXPRESSION )). Затем просто напишите результат на наш countfile:
echo "$(( counter + 1 ))" > countfile
Вероятно, вы также можете защитить свой скрипт в случае, когда countfile еще не существует, и создать один инициализированный значением 1, затем .
Все это может выглядеть так:
#!/bin/bash
if [[ -f countfile ]] ; then
read counter < countfile
else
counter=0
fi
echo "$(( counter + 1 ))" > countfile
Просто позвольте сценарию создать файл журнала, добавив, например, строку в ваш скрипт в конце:
echo "Script has been executed at $(date +\%Y-\%m-\%d) $(date +\%H-\%M-\%S)" >> ~/script.log
Таким образом вы можете отформатировать способ представления даты и времени самостоятельно, но если вы просто хотите пойти с полной датой и временем (и HH:MM:SS является приемлемым для вас форматом), вы можете просто использовать:
echo "Script has been executed at $(date +\%F-\%T)" >> ~/script.log
Тогда вы могли бы сделать:
[ f3]Что подсчитывает символы новой строки и дает вам оценку количества строк внутри файла журнала. До этого вы можете видеть в файле журнала, даже когда он был выполнен. Чтобы адаптировать его для ваших нужд, вы можете изменить пути и имена, используемые для ведения журнала. Я просто сделал здесь пример, который сохраняет файл журнала в ~.
Итак, например, вы хотите, чтобы скрипт добавлял этот счет к строке, добавленной в конце вашего скрипта, вы могли бы сделать что-то вроде этого на начало вашего скрипта:
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"
И измените вашу строку в конце скрипта на что-то, включая даже эту информацию:
echo "Script has been executed $count times at $(date +\%F-\%T)" >> ~/script.log
Это решение использует тот же подход, что и ответ Байтового Командующего, но не полагается на арифметику оболочки или другие башиды.
exec 2>&3 2>/dev/null
read counter < counter.txt || counter=0
exec 3>&2 3>&-
expr "$counter" + 1 > counter.txt
Перераспределение потоков
дублирует стандартную ошибку поток (2) в другой файловый дескриптор (3), замените его (2) перенаправлением на /dev/null (чтобы подавить сообщение об ошибке в последующем перенаправлении ввода команды read, если отсутствует файл счетчика как ожидается), затем дублируйте исходный стандартный поток ошибок (теперь на 3) на место (2) и закройте копию стандартного потока ошибок (3).У отдельного файла счетчика есть недостатки:
Для каждого файла счетчика требуется 4096 байт (или независимо от размера вашего блока). Вы должны найти имя файла в сценарии bash, а затем открыть файл, чтобы просмотреть счетчик. Нет блокировки файлов (в других ответах), поэтому возможно, что два человека обновляют счетчик в одно и то же время (это называется условием гонки в комментариях в ответ Байт Командира).Таким образом, этот ответ удаляет отдельный файл счетчика и помещает счет в сам скрипт bash!
Требуется 4096 байт (или независимо от вашего размера блока) для каждый файл счетчика. Использование flock гарантирует, что в течение короткого времени двум пользователям не удастся запустить сценарий одновременно. Вы должны найти имя файла в сценарии bash, а затем открыть файл, чтобы просмотреть счет.#!/bin/bash
# NAME: run-count.sh
# PATH: $HOME/bin
# DESC: Written for AU Q&A: https://askubuntu.com/questions/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, я написал ответ файла журнала здесь: Bash-скрипт для ведения журнала аудита / журнала файлов, к которым обращается журнал, каждый раз, когда корневые полномочия использовались с gedit или [ f7].
Уловка хотя и не используется gksu, сценарий называется gsu и вызывает pkexec «современный» способ использования sudo в графическом интерфейсе, поэтому мне говорят. [ ! d15]
Еще одно преимущество заключается не только в том, что каждый раз, когда корневые ресурсы использовались с gedit, он регистрирует имя файла, которое было отредактировано. Вот код.
~/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-gedit после нескольких правки:
__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"
Это решение использует тот же подход, что и ответ Байтового Командующего, но не полагается на арифметику оболочки или другие башиды.
exec 2>&3 2>/dev/null
read counter < counter.txt || counter=0
exec 3>&2 3>&-
expr "$counter" + 1 > counter.txt
Перераспределение потоков
дублирует стандартную ошибку поток (2) в другой файловый дескриптор (3), замените его (2) перенаправлением на /dev/null (чтобы подавить сообщение об ошибке в последующем перенаправлении ввода команды read, если отсутствует файл счетчика как ожидается), затем дублируйте исходный стандартный поток ошибок (теперь на 3) на место (2) и закройте копию стандартного потока ошибок (3).Просто позвольте сценарию создать файл журнала, добавив, например, строку в ваш скрипт в конце:
echo "Script has been executed at $(date +\%Y-\%m-\%d) $(date +\%H-\%M-\%S)" >> ~/script.log
Таким образом вы можете отформатировать способ представления даты и времени самостоятельно, но если вы просто хотите пойти с полной датой и временем (и HH:MM:SS является приемлемым для вас форматом), вы можете просто использовать:
echo "Script has been executed at $(date +\%F-\%T)" >> ~/script.log
Тогда вы могли бы сделать:
wc -l ~/script.log
Что подсчитывает символы новой строки и дает вам оценку количества строк внутри файла журнала. До этого вы можете видеть в файле журнала, даже когда он был выполнен. Чтобы адаптировать его для ваших нужд, вы можете изменить пути и имена, используемые для ведения журнала. Я просто сделал здесь пример, который сохраняет файл журнала в ~.
Итак, например, вы хотите, чтобы скрипт добавлял этот счет к строке, добавленной в конце вашего скрипта, вы могли бы сделать что-то вроде этого на начало вашего скрипта:
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"
И измените вашу строку в конце скрипта на что-то, включая даже эту информацию:
echo "Script has been executed $count times at $(date +\%F-\%T)" >> ~/script.log
У отдельного файла счетчика есть недостатки:
Для каждого файла счетчика требуется 4096 байт (или независимо от размера вашего блока). Вы должны найти имя файла в сценарии bash, а затем открыть файл, чтобы просмотреть счетчик. Нет блокировки файлов (в других ответах), поэтому возможно, что два человека обновляют счетчик в одно и то же время (это называется условием гонки в комментариях в ответ Байт Командира).Таким образом, этот ответ удаляет отдельный файл счетчика и помещает счет в сам скрипт bash!
Требуется 4096 байт (или независимо от вашего размера блока) для каждый файл счетчика. Использование flock гарантирует, что в течение короткого времени двум пользователям не удастся запустить сценарий одновременно. Вы должны найти имя файла в сценарии bash, а затем открыть файл, чтобы просмотреть счет.#!/bin/bash
# NAME: run-count.sh
# PATH: $HOME/bin
# DESC: Written for AU Q&A: https://askubuntu.com/questions/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, я написал ответ файла журнала здесь: Bash-скрипт для ведения журнала аудита / журнала файлов, к которым обращается журнал, каждый раз, когда корневые полномочия использовались с gedit или nautilus.
Уловка хотя и не используется gksu, сценарий называется gsu и вызывает pkexec «современный» способ использования sudo в графическом интерфейсе, поэтому мне говорят. [ ! d15]
Еще одно преимущество заключается не только в том, что каждый раз, когда корневые ресурсы использовались с gedit, он регистрирует имя файла, которое было отредактировано. Вот код.
~/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-gedit после нескольких правки:
__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"
Это решение использует тот же подход, что и ответ Байтового Командующего, но не полагается на арифметику оболочки или другие башиды.
exec 2>&3 2>/dev/null
read counter < counter.txt || counter=0
exec 3>&2 3>&-
expr "$counter" + 1 > counter.txt
Перераспределение потоков
дублирует стандартную ошибку поток (2) в другой файловый дескриптор (3), замените его (2) перенаправлением на /dev/null (чтобы подавить сообщение об ошибке в последующем перенаправлении ввода команды read, если отсутствует файл счетчика как ожидается), затем дублируйте исходный стандартный поток ошибок (теперь на 3) на место (2) и закройте копию стандартного потока ошибок (3).Просто позвольте сценарию создать файл журнала, добавив, например, строку в ваш скрипт в конце:
echo "Script has been executed at $(date +\%Y-\%m-\%d) $(date +\%H-\%M-\%S)" >> ~/script.log
Таким образом вы можете отформатировать способ представления даты и времени самостоятельно, но если вы просто хотите пойти с полной датой и временем (и HH:MM:SS является приемлемым для вас форматом), вы можете просто использовать:
echo "Script has been executed at $(date +\%F-\%T)" >> ~/script.log
Тогда вы могли бы сделать:
wc -l ~/script.log
Что подсчитывает символы новой строки и дает вам оценку количества строк внутри файла журнала. До этого вы можете видеть в файле журнала, даже когда он был выполнен. Чтобы адаптировать его для ваших нужд, вы можете изменить пути и имена, используемые для ведения журнала. Я просто сделал здесь пример, который сохраняет файл журнала в ~.
Итак, например, вы хотите, чтобы скрипт добавлял этот счет к строке, добавленной в конце вашего скрипта, вы могли бы сделать что-то вроде этого на начало вашего скрипта:
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"
И измените вашу строку в конце скрипта на что-то, включая даже эту информацию:
echo "Script has been executed $count times at $(date +\%F-\%T)" >> ~/script.log
У отдельного файла счетчика есть недостатки:
Для каждого файла счетчика требуется 4096 байт (или независимо от размера вашего блока). Вы должны найти имя файла в сценарии bash, а затем открыть файл, чтобы просмотреть счетчик. Нет блокировки файлов (в других ответах), поэтому возможно, что два человека обновляют счетчик в одно и то же время (это называется условием гонки в комментариях в ответ Байт Командира).Таким образом, этот ответ удаляет отдельный файл счетчика и помещает счет в сам скрипт bash!
Требуется 4096 байт (или независимо от вашего размера блока) для каждый файл счетчика. Использование flock гарантирует, что в течение короткого времени двум пользователям не удастся запустить сценарий одновременно. Вы должны найти имя файла в сценарии bash, а затем открыть файл, чтобы просмотреть счет.#!/bin/bash
# NAME: run-count.sh
# PATH: $HOME/bin
# DESC: Written for AU Q&A: https://askubuntu.com/questions/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, я написал ответ файла журнала здесь: Bash-скрипт для ведения журнала аудита / журнала файлов, к которым обращается журнал, каждый раз, когда корневые полномочия использовались с gedit или nautilus.
Уловка хотя и не используется gksu, сценарий называется gsu и вызывает pkexec «современный» способ использования sudo в графическом интерфейсе, поэтому мне говорят. [ ! d15]
Еще одно преимущество заключается не только в том, что каждый раз, когда корневые ресурсы использовались с gedit, он регистрирует имя файла, которое было отредактировано. Вот код.
~/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-gedit после нескольких правки:
__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"