I am creating a script that I will put in /etc/profile.d/namescript.sh. What it does is to add time to the history command. The script is already done, but for my change to be executed I have to close the session.
I know the source command, and if I use it to reload the profiles outside the script it works, but if I put it inside the script it does not.
My code:
#!/bin/bash
FECHA_HORA="%d/%b/%Y %H:%M"
RUTA="/etc/profile.d"
PROOT="/etc/profile"
PUSER="$HOME/.profile"
if [[ ${UID} -ne 0 ]]; then
echo "Debes ejecutar el script con permisos de admistrador: sudo ${0}"
exit 1
fi
cat <<EOF> ${RUTA}/timeHistory.sh
export HISTTIMEFORMAT="${FECHA_HORA} "
EOF
exec bash "$PROOT" && exec bash "$PUSER"
exit 0
I have tried with exec and with source inside the script, and I can not get it to work, it only works when I close session. That is why I need to reload the profile files.
Related
In Windows when I double-click a Batch script, it will automatically open a terminal window and show me what's happening. If I were to double-click a bash script in Linux, a terminal window does not open to show me what is happening; it runs in the background. I have seen that one can use one script to launch another script in a new terminal window with x-terminal-emulator -e "./script.sh", but is there any bash command I can put into the same (one) script.sh so that it will open a terminal and show me what's happening (or if I need to answer y/n questions)?
You can do something similar to what Slax
developers do in their bootinst.sh:
#!/usr/bin/env sh
#
# If you see this file in a text editor instead of getting it executed,
# then it is missing executable permissions (chmod). You can try to set
# exec permissions for this file by using: chmod a+x bootinst.sh
#
# Scrolling down will reveal the actual code of this script.
#
# if we're running this from X, re-run the script in konsole or xterm
if [ "$DISPLAY" != "" ]; then
if [ "$1" != "--rex" -a "$2" != "--rex" ]; then
konsole --nofork -e /bin/sh $0 --rex 2>/dev/null || xterm -e /bin/sh $0 --rex 2>/dev/null || /bin/sh $0 --rex 2>/dev/null
exit
fi
fi
# put contents of your script here
echo hi
# do not close the terminal immediately, let user look at the results
echo "Press Enter..."
read junk
This script would run correctly both when started in graphical
environment and in tty. It tries to restart the script inside
konsole and xterm and but if it doesn't find neither of them it
will simply run in the background.
I have a script where it will check if background_logging is true, if it is then I want the rest of the script to run in a new detached screen.
I have tried using this: exec screen -dmS "alt-logging" /bin/bash "$0";. This will sometimes create the screen, etc. but other times nothing will happen at all. When it does create a screen, it doesn't run the rest of the script file and when I try to resume the screen it says it's (Dead??).
Here is the entire script, I have added some comments to explain better what I want to do:
#!/bin/bash
# Configuration files
config='config.cfg'
source "$config"
# If this is true, run the rest of the script in a new screen.
# $background_logging comes from the configuration file declared above (config).
if [ $background_logging == "true" ]; then
exec screen -dmS "alt-logging" /bin/bash "$0";
fi
[ $# -eq 0 ] && { echo -e "\nERROR: You must specify an alt file!"; exit 1; }
# Logging script
y=0
while IFS='' read -r line || [[ -n "$line" ]]; do
cmd="screen -dmS alt$y bash -c 'exec $line;'"
eval $cmd
sleep $logging_speed
y=$(( $y + 1 ))
done < "$1"
Here are the contents of the configuration file:
# This is the speed at which alts will be logged, set to 0 for fast launch.
logging_speed=5
# This is to make a new screen in which the script will run.
background_logging=true
The purpose of this script is to loop through each line in a text file and execute the line as a command. It works perfectly fine when $background_logging is false so there are no issues with the while loop.
As described, it's not entirely possible. Specifically what is going on in your script: when you exec you replace your running script code with that of screen.
What you could do though is to start screen, figure out few details about it and redirect your console scripts in/output to it, but you won't be able to reparent your running script to the screen process as if started there. Something like for instance:
#!/bin/bash
# Use a temp file to pass cat's parent pid out of screen.
tempfile=$(tempfile)
screen -dmS 'alt-logging' /bin/bash -c "echo \$\$ > \"${tempfile}\" && /bin/cat"
# Wait to receive that information on the outside (it may not be available
# immediately).
while [[ -z "${child_cat_pid}" ]] ; do
child_cat_pid=$(cat "${tempfile}")
done
# point stdin/out/err of the current shell (rest of the script) to that cat
# child process
exec 0< /proc/${child_cat_pid}/fd/0
exec 1> /proc/${child_cat_pid}/fd/1
exec 2> /proc/${child_cat_pid}/fd/2
# Rest of the script
i=0
while true ; do
echo $((i++))
sleep 1
done
Far from perfect and rather messy. It could probably be helped by using a 3rd party tool like reptyr to grab console of the script from inside the screen. But cleaner/simpler yet would be to (when desired) start the code that should be executed in that screen session after it has been established.
That said. I'd actually suggest to take a step back and ask, what exactly is it that you're trying to achieve and why exactly would you like to run your script in screen. Are you planning to attach/detach to/from it? Because if running a long term process with a detached console is what you are after, nohup might be a bit simpler route to go.
I placed a link to my scripts in the rc.local to autostart it on linux debian boot. It starts and then stops at the while loop. It's a netcat script that listens permantently on port 4001.
echo "Start"
while read -r line
do
#some stuff to do
done < <(nc -l -p 4001)
When I start this script as root with command ./myscript it works 100% correctly. Need nc (netcat) root level access or something else?
EDIT:
rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/etc/samba/SQLScripts
exit 0
rc.local starts my script "SQLScripts"
SQLScripts
#! /bin/sh
# The following part always gets executed.
echo "Starting SQL Scripts" >> /var/log/SQLScriptsStart
/etc/samba/PLCCheck >> /var/log/PLCCheck &
"SQLScripts" starts "PLCCheck" (for example only one)
PLCCheck
#!/bin/bash
echo "before SLEEP" >> /var/log/PLCCheck
sleep 5
echo "after SLEEP" >> /var/log/PLCCheck
echo "vor While" >> /var/log/PLCCheck
while read -r line
do
echo "in While" >> /var/log/PLCCheck
done < <(netcat -u -l -p 6001)
In an rc script you have root level access by default. What does "it stops at the while loop" mean? It quits after a while, or so? I guess you need to run your loop in the background in order to achieve functionality usual in autostart scripts:
echo "Starting"
( while read -r line
do
#some stuff to do
done << (nc -l -p 4001) ) &
echo "Started with pid $( jobs -p )"
I have tested yersterday approximatly the same things, and I have discover that you can bypass the system and execute your netcat script with the following crontask. :
(every minute, but you can ajust that as you want.)
* * * * * /home/kali/script-netcat.sh // working for me
#reboot /home/kali/script-netcat.sh // this is blocked by the system.
According to me, I think that by default debian (and maybe others linux distrib) block every script that try to execute a netcat command.
Here is what I'm entering in Terminal:
curl --silent https://raw.githubusercontent.com/githubUser/repoName/master/installer.sh | bash
The WordPress installing bash script contains a "read password" command that is supposed to wait for users to input their MySQL password. But, for some reason, that doesn't happen when I run it with the "curl githubURL | bash" command. When I download the script via wget and run it via "sh installer.sh", it works fine.
What could be the cause of this? Any help is appreciated!
If you want to run a script on a remote server without saving it locally, you can try this.
#!/bin/bash
RunThis=$(lynx -dump http://127.0.0.1/example.sh)
if [ $? = 0 ] ; then
bash -c "$RunThis"
else
echo "There was a problem downloading the script"
exit 1
fi
In order to test it, I wrote an example.sh:
#!/bin/bash
# File /var/www/example.sh
echo "Example read:"
read line
echo "You typed: $line"
When I run Script.sh, the output looks like this.
$ ./Script.sh
Example read:
Hello World!
You typed: Hello World!
Unless you absolutely trust the remote scripts, I would avoid doing this without examining it before executing.
It wouldn't stop for read:
As when you are piping in a way you are forking a child which has been given input from parent shell.
You cannot give the values back to parent(modify parent's env) from child.
and through out this process you are always in parent process.
I am using an Amazon Linux AMI and doing some custom modifications(added an axis2server, etc) on it and saving it as a new AMI. Now what I want to do is when the AMI boots up, start up axis2server(ie.axis2server should automatically start when the instance boots up). For that I used a init script like below and ran the following command:
chkconfig --add axisservice
But when I launch a new instance from my image, the axis2server is not getting started.
I just only need to execute the script /home/ec2-user/axis2-1.6.1/bin/axis2server.sh at startup. Am I missing anything here?
#! /bin/sh
# Basic support for IRIX style chkconfig
###
# chkconfig: 235 98 55
# description: Manages the services you are controlling with the chkconfig command
###
case "$1" in
start)
echo -n "Starting axisservice"
touch ~/temp.txt
cd /home/ec2-user/axis2-1.6.1/bin
./axis2server.sh &
echo "."
;;
stop)
echo -n "Stopping axisservice"
echo "."
;;
*)
echo "Usage: /sbin/service axisservice {start|stop}"
exit 1
esac
exit 0
I went through https://help.ubuntu.com/community/CloudInit as well and it provides a mechanism called User-Data Scripts, where a user can execute a script when launching the script.
$ euca-run-instances --key mykey --user-data-file myscript.sh ami-axxxx
This is a command line option and what I want is something like when I launch the instance through the UI, the script should be started.Therefore, I think the above option can not be used in my case. Please correct me if I am wrong.
Thanks,
H.
I bet the environment is not set(up correctly). This means that I am guessing that your shell script tries to start another program and it's not to be found.
So at first, I'd adjust the start part of your script (current):
echo -n "Starting axisservice"
touch ~/temp.txt
cd /home/ec2-user/axis2-1.6.1/bin
./axis2server.sh &
echo "."
Edited:
echo -n "Starting axisservice"
touch ~/temp.txt
cd /home/ec2-user/axis2-1.6.1/bin
./axis2server.sh
RETVAL=$?
[ $RETVAL -eq 0 ] && echo Success
[ $RETVAL -ne 0 ] && echo Failure
echo "."
So what did I do?
removed & so script waits for your shell script (axis2server.sh) to complete
checked the return status ($?) of your shell script
Further debugging:
Add set -x to your scripts to enable tracing and log both stderr and stdout.
Questions:
Are you are aware that stop (in your service script) doesn't do anything?
touch ~/temp.txt is that supposed to create /root/temp.txt? (I'm guessing root runs this script.)
If none of my suggestions work, can you share axis2server.sh and paste stderr and stdout?