Case 1
RUN_LOG="run.log"
CMD="java -DprofileName=$PROFILE ..."
$CMD &
PID=$!
I'm able to run and get the pid.
Case 2
$CMD | tee $RUN_LOG
I'm able to run and log the result to a file..
Do you know how can I join both?
I want to log to the file and console, plus get the pid as an ENV variable.
Attempt 1:
(echo "Command PID is $BASHPID";exec $CMD;) | tee $RUN_LOG
It outputs to the file but the pid is not in a variable in the end.
Attempt 2:
$CMD & PID=$! >> $RUN_LOG
pid is in the ENV variable PID but the log file in empty.
Summary, I need to get the pid in a env variable PID, output the execution log from CMD both to console and file ("run.log")
Variables can't escape subshells. Write your pid via file or fifo instead:
tmp=$(mktemp -u)
mkfifo "$tmp"
( echo "$BASHPID" > "$tmp"; exec $CMD ) | tee "$RUN_LOG" &
pid=$(cat "$tmp")
rm "$tmp"
Related
So, I have Oh My Zsh up and running, and I'm creating my own new zsh-theme. In it, I wish to grab the external IP address from https://api.myip.com - and I'm using curl & grep to grab it. Works fine when I enter it at the command prompt, but when embedded in my zsh-theme file it gives me an error:
zsh: no matches found: ((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5]).){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])
(23) Failed writing body
Jacobs-MacBook-Pro-2.local jacobjackson ttys002 0 [ ] 10/29/20 18:32:46 PM
Here is my zsh-theme:
PROMPT='%F{white}%M %n %y %j $(curl -s https://api.myip.com | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])') %F{green}%2c%F{blue} [%f '
RPROMPT='$(git_prompt_info) %F{blue}] %F{green}%W %* %F{yellow}%D{%p}%f'
ZSH_THEME_GIT_PROMPT_PREFIX="%F{yellow}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%f"
ZSH_THEME_GIT_PROMPT_DIRTY=" %F{red}*%f"
ZSH_THEME_GIT_PROMPT_CLEAN=""
And here is the command sequence that grabs the IP address:
curl -s https://api.myip.com | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])'
Try this:
# Function name that's compatible with
# http://zsh.sourceforge.net/Doc/Release/User-Contributions.html#Prompt-Themes
# in case you ever want to build a full prompt theme.
# -s to prevent curl from outputting a progress bar.
# Use a service that simply outputs your IP, so you
# don't have to parse anything.
prompt_jacobjackson_precmd() {
psvar[1]=$( curl -s ifconfig.co )
}
# precmd hooks ru just before each new prompt.
autoload -Uz add-zsh-hook
add-zsh-hook precmd prompt_jacobjackson_precmd
# %1v inserts the 1st element of the psvar array. See
# http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html#Conditional-Substrings-in-Prompts
PS1='%1v > '
I decided to use some of Marlon Richert's ideas as well a few from the zsh-theme 'bureau.' :)
get_space () {
local STR=$1$2
local zero='%([BSUbfksu]|([FB]|){*})'
local LENGTH=${#${(S%%)STR//$~zero/}}
local SPACES=""
(( LENGTH = ${COLUMNS} - $LENGTH - 1))
for i in {0..$LENGTH}
do
SPACES="$SPACES "
done
echo $SPACES
}
_1LEFT="%F{white}$(curl -s https://api.myip.com | jq .ip -r) %F{green}\$(dirs -c; dirs)"
_1RIGHT="%F{yellow}%j jobs %F{cyan}\$(~/systemstatus.sh)"
actionjackson_precmd () {
_1SPACES=`get_space $_1LEFT $_1RIGHT`
#print
print -rP "$_1LEFT$_1SPACES$_1RIGHT"
}
setopt prompt_subst
PROMPT='%F{yellow}%n%F{white}#%F{green}%M $_LIBERTY%f '
RPROMPT='$(actionjackson_git_prompt) %F{green}%W %* %F{yellow}%D{%p}%f'
autoload -U add-zsh-hook
add-zsh-hook precmd actionjackson_precmd
This is a little complicated case for me.
I want to track if the 'script1_sparkSubmit01.sh' is completed or not which is triggered by Main.sh; if not then wait for it to complete; if completed, then proceed with the remaining script(s) in the main.sh.
Main Script: Main.sh
ksh script1_sparkSubmit01.sh 2>&1 &
pid=$!
echo $pid
while [ 1 ]
do
[ -n "$pid" ] && sleep 60 || break
done
ksh script2_sparkSubmit02.sh 2>&1 &
Another script: script1_sparkSubmit01.sh
spark-submit --jars $sqldriver_jar_path $spark_jar_path/table-load_2.11-1.0.jar >> ${log_dir}/$log_file_name1 2>&1 &
Currently, pid is giving some random value which when I lookup is not available in the current shell. However, I see the 'spark-submit' command of script1_sparkSubmit01.sh running in the current shell.
Kindly help.
Taking the PID from the script which 'script1_sparkSubmit01.sh' triggers - did work out to me.
ksh script1_sparkSubmit01.sh 2>&1 &
while [ 1 ]
do
pid=$(ps -aux | grep 'table-load_2.11-1.0.jar' | grep -v "grep" | awk '{print $2}')
[ -n "$pid" ] && sleep 30 || break
done
ksh script2_sparkSubmit01.sh 2>&1 &
I have written a ZSH function whose output is a command line which runs a program I need the user to be able to interact with.
At the moment I just echo the command line and instruct the user to copy-paste it so that they have the necessary access to its pipes, however is there a way I can just have the function finish by entering the command for the user as if they had copied and pasted it themselves?
I have looked into using zle but that seems to require a key binding, whereas I just want the user to be able to run: myzshfunction arg1 and the ultimate result to be their terminal attached to the program launched as a result of some processing of their arg1.
$ myzshfunction arg2*2
Run this command! foobar baz4
$ foobar baz4
...
The function looks something like this:
myzshfunction() {
if [[ $# = 0 ]]
then
echo "usage: myzshfunction 1.2.3.4"
return
fi
local creds=`curl "https://xxx/$1/latest" | jq -r 'x'`
local cred_arr=("${(#s|/|)creds}")
local pwd_pipe=$(mktemp -u)
mkfifo $pwd_pipe
exec 3<>$pwd_pipe
rm $pwd_pipe
echo $cred_arr[2] >&3
echo "Run this: sshpass -d3 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$cred_arr[1]#$1"
exec 3>&-
}
TIA
Use print -z to add text to the buffer. From the documentation:
-z Push the arguments onto the editing buffer stack, separated by spaces.
Calling foo, defined below, will result in hi being placed on the command line as if the user had typed it. For example,
% foo () { print -z hi; }
% foo
% hi
The best solution I could come up with was to use zle - the Zsh Line Editor.
This lets you update the command the user is currently editing, which to me feels a bit hacky. I would prefer a solution that lets you call a function, hit return, and then cleanly run a function with STDIO attached to your terminal as if you had run the resulting command line.
Perhaps you could emulate this by bindkey'ing the return key and doing some sort of decision/routing from there to see if the user wants to call myfunc. For now, my solution requires the Esc+i sequence is entered after typing a target for $host.
zle-myfunc() {
apikey=$(keychain-environment-variable api-key)
if [ $? -ne 0 ]; then
echo "Add your api-key to the keychain: "
BUFFER='security add-generic-password -U -a ${USER} -D "environment variable" -s "api-key" -w'
zle accept-line
return 1
fi
local host=$BUFFER
zle kill-buffer
local creds=`curl ..." | jq -r ...`
if [ -z creds ]; then
echo "Couldn't get creds, check your network"
return 1
fi
local creds_arr=("${(#s|/|)creds}")
local pwd_pipe=$(mktemp -u)
mkfifo $pwd_pipe
exec 3<>$pwd_pipe
# anonymise the pipe
rm $pwd_pipe
echo "$creds_arr[2]" >&3
BUFFER="sshpass -d3 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $creds_arr[1]#$host"
zle accept-line
# exec 3>&-
}
zle -N zle-myfunc
bindkey '\ei' zle-myfunc
I am writing a script where I am grepping for a word and if it is true it should exit script else should continue the script. But my script is not going to else part even when grep output is false.
ps -fu rdb1 | grep humor >> humor_chk
grep humor.pl humor_chk | tail -1
if [ $? -eq 0 ]
then
echo "`date +%D' '%T` Humor is still running. Hence exiting" >> $LOG1
exit
else
ls -lrt /a/b/c/ >> files
fi
I am getting the output as:
01/19/15 05:54:03 Humor is still running. Hence exiting
I figured it out.
GREPOUT=`grep "NOTE: Table $TABLE created," $LOGFILE | awk '{print $6}'`
NIW=`grep "SYMBOLGEN: Macro variable NIW resolves to" $LOGFILE | awk '{print $0}'`
if [ "$GREPOUT" -gt "0" ]; then
echo "$NIW" |\
$MAILX -s "SUCESSFUL BATCH RUN: $PROG $RPTDATE" $MAILLIST
fi
from the body of the sent email
SYMBOLGEN: Macro variable NIW resolves to 8
My script runs a SAS code and sends out an email after it completes.
I'm looking to print the contents of a table or list of macro variables in the email.
The SAS code has a %put all; statement at the end so all macro variables are listed in the log.
Thanks.
#If it's gotten this far, we can safely grab the number of rows
#of output from $LOGFILE.
GREPOUT=`grep "NOTE: Table $TABLE created," $LOGFILE | awk '{print $6}'`
NIW=`grep "GLOBAL NIW" $LOGFILE | '(print $6)'`
if [ "$GREPOUT" -gt "0" ]; then
#echo "$GREPOUT rows found in $TABLE." |\
echo "$NIW NIW" |\
$MAILX -s "SUCESSFUL BATCH RUN: $PROG $RPTDATE" $MAILLIST
else
echo "$GREPOUT rows found in $TABLE." |\
$MAILX -s "SUCESSFUL BATCH RUN: $PROG $RPTDATE" $MAILLIST
fi