Author Topic: Linux shell script to log and timestamp terminal input and display that log  (Read 1141 times)

0 Members and 1 Guest are viewing this topic.

Offline orneaTopic starter

  • Supporter
  • ****
  • Posts: 135
  • Country: au
My shell (redhat bash) scripting powers are very weak.

I have searched for ways to create simple script (lets call it ow.sh) that when run will tail the contents of a file (lets call it ow.txt) and append any STDIN to that file with a timestamp.

The idea is many users can ssh sally@server /path/path/ow.sh

The terminal will then display the last ~10 entries in the ow.txt and wait for input and will update if there are any changes made to the file like tail -f does.

Any input that is followed by <Enter> will be appended to the file with a time stamp

All I have thus far is a script that appends a timestamp to a file (borrowed from elsewhere)

Code: [Select]
f=ow.txt
tmp=$(mktemp)
(tail "$f";date;) > "$tmp" && mv "$tmp" "$f"

I think 'tee' along with some >1 & <2 type hieroglyphics will be useful here but not sure how

Example contents of ow.txt
Code: [Select]
3 Feb 2023 7:05am [charlie] Server Peanuts has been bounced as requested and is back up
3 Feb 2023 7:15am [snoopy] Yep, we can see that, all good now, thanks for your help
3 Feb 2023 7:25am [sallly] Thanks Charles. You guys seen watchmeforever by any chance. Its ... different

It appears to be a 'trival' task with all the funky io redirect features that linux has, but if it proves otherwise I can always create a python script as a fall back.

Would welcome any tricks, hints or complete solutions

Cheers Ornea
 

 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4028
  • Country: nz
Here's a one-liner. Adjust date format to suit, and pipe it as you wish.

Code: [Select]
perl -pe '$d = localtime(); $_ = "$d: $_"'

For those unfamiliar, the "-p" flag to Perl puts a loop around your code that reads stdin line by line into $_, and then prints $_ after your code. So I simply modify what is in $_ (the current line).
« Last Edit: February 02, 2023, 11:55:55 pm by brucehoult »
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3035
  • Country: us
 
The following users thanked this post: DiTBho

Offline magic

  • Super Contributor
  • ***
  • Posts: 6758
  • Country: pl
The idea is many users can ssh sally@server /path/path/ow.sh

The terminal will then display the last ~10 entries in the ow.txt and wait for input and will update if there are any changes made to the file like tail -f does.

Any input that is followed by <Enter> will be appended to the file with a time stamp
Multiple concurrent users?

What happens if I'm halfway through writing a line and somebody else also adds a line?
Obviously, we wouldn't want to mix these lines in the file, and this can be assured by buffering a full line before writing anything.
But what is supposed to happen to the text display on my screen when this occurs, and how?

This doesn't look trivial, it seems you want to implement some sort of chat?
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6239
  • Country: fi
    • My home page and email address
Make sure you have bash and flock (from util-linux package) installed –– they are in all Linux distros by default ––, create /var/log/eventlog.user with appropriate rw access to the group of users that are allowed to use this, and save the following as a script those users can execute:
Code: [Select]
#!/bin/bash

# EVENTFILE: path to the event file
export EVENTFILE=/var/log/eventlog.user

# EVENTS: number of events to show; default 20, overridable
EVENTS=$(($EVENTS-0))
[[ $EVENTS -le  0 ]] && EVENTS=20

while [[ 1 ]]; do
    clear
    printf 'Events up to %s:\n' "$(date '+%Y-%m-%d %H:%M:%S %z')" >&2
    flock -s "$EVENTFILE" tail -n $EVENTS "$EVENTFILE"
    printf 'Enter to refresh, CTRL+D to exit, or text for new entry:\n' >&2
    printf '> ' >&2

    read Line || break

    # Remove leading and trailing whitespace
    Line="${Line//[[:space:]]/ }"
    Line="${Line# }"
    Line="${Line% }"
    if [[ -n "$Line" ]]; then
        export MSG="$(date '+%Y-%m-%d %H:%M:%S %z') $(id -un): ${Line}"
        flock -e "$EVENTFILE" -c 'echo "$MSG" >> "$EVENTFILE"'
    fi
done
printf '[Ctrl-D]\n' >&2
It works absolutely fine even if multiple users use it at the same time, because it uses flock to advisory-log the event log file during reading and appending.  The downside is that new entries are not automatically shown, the user must press Enter to see any new messages.

If you were to put the display of the log and appending to the log into separate shell scripts (/usr/share/eventlog/list and /usr/share/eventlog/add for example, controlled by environment variables EVENTFILE and EVENTS), it would be very easy to have them color-code the output, too, if so desired (and if the connection is to a tty: if $(stty &>/dev/null); then is-a-tty; else not-a-tty; fi).

Personally, however, I'd write a small C program for this, using ncursesw, so that it'd work like a real-time chat, except using the file for the chat record.
Lemme know if that would be useful; other members here could perhaps suggest useful notation (like auto-highlighting patterns like [space]@[username]).[/code]
« Last Edit: February 03, 2023, 11:37:25 am by Nominal Animal »
 
The following users thanked this post: DiTBho

Offline shapirus

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: ua
I have searched for ways to create simple script (lets call it ow.sh) that when run will tail the contents of a file (lets call it ow.txt) and append any STDIN to that file with a timestamp.
Code: [Select]
$ sudo apt install moreutils
$ man ts

p.s. sorry I missed that you use redhat. You'll obviously need to use yum (or whatever the today's redhat package management tool of the day is) instead of apt, and the package name may be different. It may well be already installed too.
« Last Edit: February 07, 2023, 12:44:59 am by shapirus »
 

Offline orneaTopic starter

  • Supporter
  • ****
  • Posts: 135
  • Country: au
I will attempt some of the suggestions.  Thankyou all for taking the time.

I should have mentioned that the OS is locked down so I cant add anything except what I enter via a keyboard.

I was having some success creating a script that launches two xterm's. One for input and one for output side by side.  Just need to iron out the bugs when ssh-ing.

Interesting that tail -f does not work in this setup over nfs so solved with tail -n executed regularly.

Definitely not as trivial as I first thought
« Last Edit: February 07, 2023, 08:23:17 am by ornea »
 

Offline orneaTopic starter

  • Supporter
  • ****
  • Posts: 135
  • Country: au
Solution I used if useful to others.

Given the system restraints simple solution was to create a launcher bash script that opened two separate gnome terminal sessions that ssh'es to a server and launces that two scripts i.e. ssh user@server owInput.sh  .  One for input, and one for output.  The launcher also pkill'ed any existing sessions if running.

Input simply waited for user input and appended it to a file with date stamp and the user and then calls it self.

Output tail'ed the file in a while loop (as tail -f did not work)

Thankyou all for your input
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf