script gets a bug when I record Shell output - linux

I wanted to know how to record all the input and output of my terminal.
Of course, I can use the script command but I am going to record every user's input and output. So I put script into file: .barhrc for every user's home directory.
Just like this:
script -a -f -q $RECORDFILE
But I met a bug when other program or Shell script executed source ~/.bashrc. Because source ~/.bashrc go into a new shell environment,so it stops my script from going any further util I use the exit command and stop the recording.
I'm sorry for my poor English.
Thanks in advance!

You can set a variable and also check that input is a TTY:
if [[ -z "$RECORDING" && -t 0 ]]
then
RECORDING="YES" exec script -afq "$RECORDFILE"
fi
The variable ensures that you will not start recording in a session that is already being recorded.
Checking that input is a terminal ensures that any script running from cron or similar will not try to start recording, even if such a script runs source ~/.bashrc to try to set up some variables.
You should also see whether ~/.bash_profile is a better place to start recording. This file runs only on login, and scripts usually don't try to source it. However, some terminal emulators will not start up with login shells, so they may not start recording.

Related

linux "enable -n xxx" command works in terminal but not when put into a script

I've found a very strange issue, when in linux terminal I type "enable -n trap", it would disable the trap linux builtin command. But if I put it into a script like
#!/bin/bash
enable -n trap
and then run the script, there's no error but the command is also not disabled. Really appreciate if someone could share what is happening and how to run it in some file instead of directly in the terminal. Thank you!
The enable command only affects the current shell. When you run a script, that script is executed in a new process, so:
A new shell starts
The enable command runs and disables the trap command in that shell
The shell exits
If you want to affect the current shell, your only option is to source the script using the . (or source) command. If the script is named disable-trap.sh and is in your $PATH, you can run:
. disable-trap.sh
You can also provide a full path to the script:
. /path/to/disable-trap.sh
Sourcing a script like this is largely equivalent to typing the same commands in at the command line: it executes the instructions in the script in the current shell, rather than spawning a new process.

Cannot start grabserial on Raspberry pi boot

I have a problem with starting a bash script data.sh, which is using grabserial to get data from serial input and store them in the .txt file (if it doesn't exist, it creates it):
#!/bin/bash
grabserial -v -d /dev/ttyAMA0 -b 9600 -w 8 -p N -s 1 -o /home/pi/serialLog.txt
After booting there is not however any serialLog.txt file created, therefore I think it doesn't run properly (manually running the script creates the .txt file immedeately). My goal is to run that script on the background (as I could have achieved manually by starting it in screen and then detach the window). I tried to write the path of the script to /etc/rc.local (of course also set up the privileges of data.sh to 755) like that:
/home/pi/data.sh &
exit 0
Because my grabserial should run infinitely, I have put the & behind, which if I understand it correctly, makes fork and next command doesn't need the previous one to be finished.
If I try another code in bash not using grabserial, it works perfectly. Could you please tell me, whether I am doing anything wrong using grabserial? Thank you, Kaki
the filename must be between hyphens:
-o "filename"

Unable to run X11 (graphical) programs from atd

I am trying to schedule the execution of a shell-script with the Linux tool "at".
The shell script (video.sh) looks like this:
#!/bin/sh
/usr/bin/vlc /home/x/video.mkv
The "at" command:
at -f /home/x/video.sh -t 201411052225
When the time arrives, nothing happens.
I can execute the shell-script just fine via console or by rightclicking - Execute. VLC starts like it is supposed to. If I change the script to e.g. something simple like
#!/bin/sh
touch something.txt
it works just fine.
Any ideas, why "at" will not properly execute a script that starts a graphical program? How can I make it work?
You're trying to run an X command (a graphical program) at a scheduled time. This will be extremely difficult, and quite fragile, because the script won't have access to the X server.
At the very least, you will need to set DISPLAY to the right value, but even then, I suspect you will have issues with authorisation to use the X screen.
Try setting it to :0.0 and see if that works. But if you're logged out, or the screensaver's on, or any number of other things...
(Also, redirect vlc's stdout and stderr to a file so that you can see what went wrong.)
Your best bet might be to try something like xuserrun.
I suspect that atd is not running. You have to start the atd daemon before (and to set DISPLAY variable like chiastic-security said) ;)
You can test if atd is running with
pidof atd &>/dev/null && echo 'ATD started' || echo >&2 'ATD not started
Your vlc command should be :
DISPLAY=:0 /usr/bin/vlc /home/x/video.mkv
(Default display)

Running a script in the background before logging in

I have a python script that I want run prior to any user logging in. This is for a home automation server and I want it always to be up and running as soon as the system allows.
I already have it in the rc.local file including an ampersand. This works.
But I can't see the screen output that it produces.
When I log into the unit (it's a raspberry pi running raspian) via SSH I can start it using screen which works the best as when I logout and back in, it's still there. AND I can see the output from the script.
But when I try running screen from the rc.local file, and subsequently login to check, the script isn't there (ie ps aux | grep script.py confirms)
edit: I've taken on Nirk's solution below about using tail. From the command line, it works fine. But starting it form within /etc/rc.local doesn't. I have touched the file and everyone has write access to it.
This is what's in my rc.local file:
python /home/pi/gateway.py &> /x10.log &
UPDATE
This is how I did it in the end:
Although the question was just about how to run in the background prior to login, there was more to it. The script is a work in progress and because of the way a particular serial device acts with it, it is/was prone to crashing (I've almost got all the bugs out of it). I needed to be able to restart it as well. I tried nohup but for some reason, it wouldn't keep it alive so in the end I found the top answer from this page got it all sorted.
In my /etc/rc.local I included a shell script to run:
nohup /home/pi/alwaysrun.sh > /home/pi/mha.log 2>&1 &
alwaysrun.sh contains:
#!/bin/bash
until python /home/pi/gateway.py; do
echo "'gateway.py' exited with exit code $?. Restarting..." >&2
sleep 1
done
nohup will keep the alwaysrun.sh script alive, and that in turn keeps my gateway.py script running. The redirect of stdout and stderr means I can setup a tail (and/or go back and check) the log.
Instead of using screen, if you just want to see the output you should redirect the output of the command to a log file and then tail the file.

Bash Command Logger

I was wondering, out of curiosity, if it is possible to code a bash script logs all the command run in a Bash/SSH session. I know history is suppose to log all the commands run but it seems to be very unreliable!
I have been messing about this morning and came up with the following bash script which does log what the user runs in the terminal but does not run all the commands correctly.
prompt_read() {
echo -n “$(whoami)#$(hostname):$(pwd)~$ “
read userinput
}
prompt_read
while :; do
if [[ $userinput != exit ]]; then
logger "logit $userinput"
bash -c "$userinput"
prompt_read
else
kill -1 $PPID
fi
done
Is anyone aware of anything that logs commands better and more reliably than history
Cheers
The reason why history seems unreliable to you is because it only writes to history at the end of a BASH session, so you could lose commands.
I have a few things in my bash profile:
HISTFILESIZE=10000 # how many lines of history to store in the history file
HISTSIZE=10000 # how many lines of history to store in a session ( I think )
HISTCONTROL=ignoredups # ignore duplicate commands
shopt -s histappend # append history, rather than having sessions obliterate existing history
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
The last few are the important ones, setting your PROMPT_COMMAND with history -a will make history append immediately, rather than post-session. And setting shopt -s histappend will make bash sessions append to the history file, rather than overwrite existing histories.
Some more info: http://linuxcommando.blogspot.com/2007/11/keeping-command-history-across-multiple.html
Additionally, if this is useful to you, you can change the name of the history file you use for a particular bash session with the HISTFILE environment variable.
Check out script: http://bashshell.net/commands/using-the-script-command/
It records everything that appear on the terminal to a file, and iirc it can play back the recorded session.
You can set this as the user's shell to make it record everything upon login.
You can find a script here to log all 'bash' commands/builtins into a text-file or a 'syslog' server without using a patch or a special executable tool.
You can also write directly without syslog to a logfile.
It is very easy to deploy, as it is a simple shell script that need to be called once at the initialization of the 'bash'.

Resources