I am looking at various Jenkins projects which have shell commands being executed as part of the build process. They are referencing and modifying variables that are not defined anywhere in the project.
I am trying to figure out what environment these shell scripts are being executed in. I read the JenkinsWiki but it did not really explain what the PWD of the shell during processing of a particular Jenkins job. Googling jenkins directory structure yields results which are mostly concerned with the internals of Jenkins itself, not the execution environment of my build jobs. What directory shell commands in Jenkins execute in?
You can find the current working directory of a process using the proc subsystem:
# Get the PID using something like this:
PID=$( ps -o pid,cmd | grep jenkin[s] | awk '{print $1}' | head -n 1 )
# Use the proc subsystem
ls -l /proc/$PID/cwd
Related
I am very new to shell scripting, can anyone help to solve a simple problem: I have written a simple shell script that does:
1. Stops few servers.
2. Kills all the process by user1
3. Starts few servers .
This script runs on the remote host. so I need to ssh to the machine copy my script and then run it. Also Command I have used for killing all the process is:
ps -efww | grep "user1"| grep -v "sshd"| awk '{print $2}' | xargs kill
Problem1: since user1 is used for ssh and running the script.It kills the process that is running the script and never goes to start the server.can anyone help me to modify the above command.
Problem2: how can I automate the process of sshing into the machine and running the script.
I have tried expect script but do I need to have a separate script for sshing and performing these tasksor can I do it in one script itself.
any help is welcomed.
Basically the answer is already in your script.
Just exclude your script from found processes like this
grep -v <your script name>
Regarding running the script automatically after you ssh, have a look here, it can be done by a special ssh configuration
Just create a simple script like:
#!/bin/bash
ssh user1#remotehost '
someservers stop
# kill processes here
someservers start
'
In order to avoid killing itself while stopping all user's processes try to add | grep -v bash after grep -v "sshd"
This is a problem with some nuance, and not straightforward to solve in shell.
The best approach
My suggestion, for easier system administration, would be to redesign. Run the killing logic as root, for example, so you may safely TERMinate any luser process without worrying about sawing off the branch you are sitting on. If your concern is runaway processes, run them under a timeout. Etc.
A good enough approach
Your ssh login shell session will have its own pseudo-tty, and all of its descendants will likely share that. So, figure out that tty name and skip anything with that tty:
TTY=$(tty | sed 's!^/dev/!!') # TTY := pts/3 e.g.
ps -eo tty=,user=,pid=,cmd= | grep luser | grep -v -e ^$TTY -e sshd | awk ...
Almost good enough approaches
The problem with "almost good enough" solutions like simply excluding the current script and sshd via ps -eo user=,pid=,cmd= | grep -v -e sshd -e fancy_script | awk ...) is that they rely heavily on the accident of invocation. ps auxf probably reveals that you have a login shell in between your script and your sshd (probably -bash) — you could put in special logic to skip that, too, but that's hardly robust if your script's invocation changes in the future.
What about question no. 2? (How can I automate sshing...?)
Good question. Off-topic. Try superuser.com.
My problem is specific to the running of SPECCPU2006(a benchmark suite).
After I installed the benchmark, I can invoke a command called "specinvoke" in terminal to run a specific benchmark. I have another script, where part of the codes are like following:
cd (specific benchmark directory)
specinvoke &
pid=$!
My goal is to get the PID of the running task. However, by doing what is shown above, what I got is the PID for the "specinvoke" shell command and the real running task will have another PID.
However, by running specinvoke -n ,the real code running in the specinvoke shell will be output to the stdout. For example, for one benchmark,it's like this:
# specinvoke r6392
# Invoked as: specinvoke -n
# timer ticks over every 1000 ns
# Use another -n on the command line to see chdir commands and env dump
# Starting run for copy #0
../run_base_ref_gcc43-64bit.0000/milc_base.gcc43-64bit < su3imp.in > su3imp.out 2>> su3imp.err
Inside it it's running a binary.The code will be different from benchmark to benchmark(by invoking under different benchmark directory). And because "specinvoke" is installed and not just a script, I can not use "source specinvoke".
So is there any clue? Is there any way to directly invoke the shell command in the same shell(have same PID) or maybe I should dump the specinvoke -n and run the dumped materials?
You can still do something like:
cd (specific benchmark directory)
specinvoke &
pid=$(pgrep milc_base.gcc43-64bit)
If there are several invocation of the milc_base.gcc43-64bit binary, you can still use
pid=$(pgrep -n milc_base.gcc43-64bit)
Which according to the man page:
-n
Select only the newest (most recently started) of the matching
processes
when the process is a direct child of the subshell:
ps -o pid= -C=milc_base.gcc43-64bit --ppid $!
when not a direct child, you could get the info from pstree:
pstree -p $! | grep -o 'milc_base.gcc43-64bit(.*)'
output from above (PID is in brackets): milc_base.gcc43-64bit(9837)
As per project requirement, i need to check the content of zip file generated which been generated on remote machine.This entire activity is done using automation framework suites. which has been written in shell scripts. I am performing above activity using ssh command abd execute unzip command with -l and -q switches. But this command is getting failed. and shows below error messages.
[SOMEUSER#MACHINE IP Function]$ ./TESTS.sh
ssh SOMEUSER#MACHINE IP unzip -l -q SOME_PATH/20130409060734*.zip | grep -i XML |wc -l
unzip: cannot find or open SOME_PATH/20130409060734*.zip, SOME_PATH/20130409060734*.zip.zip or SOME_PATH/20130409060734*.zip.ZIP.
No zipfiles found.
0
the same command i had written manually but that works properly. I really have no idea.Why this is getting failed whenever i executed via shell scripts.
[SOMEUSER#MACHINE IP Function]$ ssh SOMEUSER#MACHINE IP unzip -l -q SOME_PATH/20130409060734*.zip | grep -i XML |wc -l
2
Kindly help me to resolve that issue.
Thanks in Advance,
Priyank Shah
when you run the command from your local machine, the asterisk character is being expanded on your local machine before it is passed on to your remote ssh command. So your command is expecting to find SOME_PATH/20130409060734*.zip files on your machine and insert them into your ssh command to be passed to the other machine, whereas you (I'm assuming) mean, SOME_PATH/20130409060734*.zip files on the remote machine.
for that, precede the * character by a backslash ( \ ) and see if it helps you. In some shells escape character might be defined differently and if yours is one of them you need to find the escape character and use that one instead. Also, use quotes around the commands being passed to other server. Your command line should look something like this in my opinion:
ssh SOMEUSER#MACHINE_IP "/usr/bin/unzip -l -q SOME_PATH/20130409060734\*.zip | grep -i XML |wc -l"
Hope this helps
I wrote a Perl program to capture a live data stream from a tail command on a Linux machine using the following command in the console:
tail -f xyz.log | myperl.pl
It works fine. But now I have to execute this Perl program on a different machine because the log file is on that different machine. Can anyone tell me how I can do it?
You could say
ssh remotemachine tail -f xyz.log | myperl.pl
I suppose or maybe mount the remote log directories locally onto your administrative machine and do the processing there.
Or you could even say
ssh remotemachine bash -c "tail -f xyz.log | myperl.pl"
in order to run the script on the remote machine (if your script produces some output files and you want them on remote machine)
I have this running:
if (open(PS_ELF, "/bin/ps -eLf|")) {
while (<PS_ELF>) {
if ($_ =~ m/some regex/) {
# do some stuff
}
}
}
If called locally, the loop runs just fine, once for every output line of ps -eLf
Now if the same script is called from Nagios via NRPE, PS_ELF does only contain one line (the first line output by ps).
This puzzles me; what could be the reason?
Maybe this is not limited to/caused by Nagios at all, I just included it for the sake of completeness.
I'm on SUSE Enterprise Linux 10 SP2 and perl v5.8.8.
Although this problem is very old, I experienced the exact same problem today.
So I thought I share what I found.
The problem is that processes created by the NRPE daemon (can) have a different environment than processes you execute directly in the shell as the NRPE daemon user.
I created the following bash script:
#!/bin/bash
echo `env | grep COLUMNS`
This gives me the environment variable COLUMN of the current process, which has the same environment as the parent process (the process forked by the NRPE daemon).
When I execute this script as the NRPE daemon user
$ /tmp/check_env.sh
COLUMNS=174
it gives me the value of my current shell window.
But when I execute this script via NRPE, I get:
nagios-server $ check_nrpe -H client -c check_env
COLUMNS=80
Which is why ps -eaf output is limited to 80 characters unless you use the ww parameter for unlimited width, which ignores the COLUMNS environment variable.
I changed 'ps -eLf' to 'ps -eLfww' (ww for unlimited output) and this fixed the problem even if I don't understand why there is a difference when called remotely.
It's probably more something to do with how NRPE plugins work than Perl itself.
Your plugin is working like explained here (return code + output) ?