I have the following shell script to open an xterm window and install a repo.
#!/bin/bash
REPO_NAME=$1
REPO_DIR=$2
REPO_URL=$3
REPO_BRANCH=$4
CLONE="git clone --recursive $REPO_URL $REPO_NAME"
DIR="cd $REPO_DIR"
CHECKOUT="git checkout $REPO_BRANCH"
COMMAND="$CLONE && $DIR && $CHECKOUT"
xterm -T $REPO_DIR -geometry 90x30 -e "$COMMAND"
What I want to do is close xterm if $COMMAND runs with no errors. If there is an error I want to keep the window open, how can I do this?
I am aware of the -hold parameter but this keeps the window open even if $COMMAND passes. I only want it to be open if it FAILS
I suggest:
xterm -T $REPO_DIR -geometry 90x30 -e "$COMMAND || read"
or
xterm -T $REPO_DIR -geometry 90x30 -e "$COMMAND || read -p 'Press return to close window'"
You can use the $? variable to get the exit status of the previous program. Most programs return 0 as exit code on success. You can test it with a simple if construction.
Related
I have a .sh script that works fine if I run it in Terminal using "/Volumes/MEDIA/SERVER/SYNC.sh"
But I can not get it to run the same in AppleScript Editor using:
do shell script "/Volumes/MEDIA/SERVER/SYNC.sh"
Also tried the above with bash in front, sh in front.
The shell script (SYNC.sh)
#!/bin/bash
login="uhh"
pass="uhh"
host="uhh.com"
remote_dir='~/private/sync'
local_dir="/Volumes/MEDIA/_/SYNCING"
base_name="$(basename "$0")"
lock_file="/tmp/$base_name.lock"
trap "rm -f $lock_file" SIGINT SIGTERM
if [ -e "$lock_file" ]
then
echo "$base_name is running already."
exit
else
touch "$lock_file"
lftp -p 22 -u "$login","$pass" sftp://"$host" << EOF
set sftp:auto-confirm yes
set mirror:use-pget-n 5
mirror -c -P5 --Remove-source-files --log="/Volumes/MEDIA/SERVER/LOGS/$base_name.log" "$remote_dir" "$local_dir"
quit
EOF
# MOVE FINISHED FILES INTO DIRECTORY FOR CONVERSION
mv /Volumes/MEDIA/_/SYNCING/movies/* /Volumes/MEDIA/SEEDBOX/MOVIES
mv /Volumes/MEDIA/_/SYNCING/tvshows/* /Volumes/MEDIA/SEEDBOX/TVSHOWS
mv /Volumes/MEDIA/_/SYNCING/books/* /Volumes/MEDIA/SEEDBOX/BOOKS
mv /Volumes/MEDIA/_/SYNCING/music/* /Volumes/MEDIA/SEEDBOX/MOVIES
# SHOW COMPLETED NOTIFICIATION
osascript -e 'display notification "Sync completed" with title "SEEDB0X"'
rm -f "$lock_file"
trap - SIGINT SIGTERM
exit
fi
By not 'the same' what happens is only the
osascript -e 'display notification "Sync completed" with title "SEEDB0X"'
is run. With the script running through Terminal that only appears once syncing is done.
Thanks for any help!
Did you install lftp yourself? I don't have a Mac handy to check if it's in Mac OS X by default or not. If you installed it, then it probably isn't in the PATH of the AppleScript environment and the bash script can't find it when run from there.
If this is the case, then you'll have to either:
Fully qualify the path to 'lftp' (eg, "/usr/local/bin/lftp" or where ever it actually is)
or
Append to the PATH environment variable as used by AppleScript (or early in your bash script).
I think I'd go for option 1. Option 2 is overkill and more likely to adversely affect other things at other times.
PS. If you don't know where 'lftp' is installed, type 'which lftp' in the terminal.
I need to open a new terminal tab and execute multiple commands on it, how can I do it. I have already tried the following,
gnome-terminal --tab -t "X" -e "cd ~/Desktop/terminal_test;mkdir test"
Here I need to cd into a new directory and create a new folder.
Try this:
gnome-terminal -x bash -c "cmd1; cmd2; …cmdN; exec bash"
You can use gnome-terminal. The script below will open 3 tabs running the respective commands..
tab="--tab"
cmd01="bash -c 'ls';'pwd';bash"
foo=""
foo+=($tab -e "$cmd01")
gnome-terminal "${foo[#]}"
exit 0
I want to start the bash with 4 tabs, having different titles. In all of them I'm working in different directories so it would be useful if I can cd to different paths.
Now it would be also great to save the history separately for every tab. So that every tab only remembers the commands I ran on it, even after a reboot.
Currently I have a script which starts gnome-terminal with 4 tabs.
gnome-terminal --geometry=150x50 --tab --title="src" -e "bash -c \"cd "~/path/to/src";exec bash\"" --tab --title="first test" -e "bash -c \"cd "~/path/to/single-test-dir";exec bash\"" --tab --title="test3" -e "bash -c \"cd "~/path/to/testdir";exec bash\"" --tab --title="test4" -e "bash -c \"cd "~/path/to/somewhere";exec bash\""
I suppose you can use a gnome-terminal custom command for each profile, for example
bash -c 'PROFILE=default_profile exec bash'
or
bash -c 'PROFILE=screen_profile exec screen -U'
or similar.
Then in ~/.bashrc
if [[ -n $PROFILE ]]; then
HISTFILE=~/.bash_history."$PROFILE"
fi
source of the answer.
After trying to figure out why a Capistrano task (which tried to start a daemon in the background) was hanging, I discovered that using && in bash over ssh prevents a subsequent program from running in the background. I tried it on bash 4.1.5 and 4.2.20.
The following will hang (i.e. wait for sleep to finish) in bash:
ssh localhost "cd /tmp && nohup sleep 10 >/dev/null 2>&1 &"
The following won't:
ssh localhost "cd /tmp ; nohup sleep 10 >/dev/null 2>&1 &"
Neither will this:
cd /tmp && nohup sleep 10 >/dev/null 2>&1 &
Both zsh and dash will execute it in the background in all cases, regardless of && and ssh. Is this normal/expected behavior for bash, or a bug?
One easy solution is to use:
ssh localhost "(cd /tmp && nohup sleep 10) >/dev/null 2>&1 &"
(this also works if you use braces, see second example below).
I did not experiment further but I am reasonably convinced it has to do with open file descriptors hanging around. Perhaps zsh and dash bind the && so that this means what has to be spelled as:
{ cd /tmp && nohup sleep 10; } >/dev/null 2>&1
in bash.Nope, quick experiment in dash shows that echo foo && echo bar >file only redirects the latter. Still, it has to have something to do with lingering open fd's causing ssh to wait for more output; I've run into this a lot in the past.
One more trick, not needed if you use the parentheses or braces for this particular case but might be useful in a more general context, where the set of commands to do with && are more complex. Since bash seems to be hanging on to the file descriptor inappropriately with && but not with ;, you can turn a && b && c into a || exit 1; b || exit 1; c. This works with the test case:
ssh localhost "true || exit 1; echo going on; nohup sleep 10 >/dev/null 2>&1 &"
Replace true with false and the echo of "going on" is omitted.
(You can also set -e, although sometimes that is a bigger hammer than desired.)
This seems to work:
ssh localhost "(exec 0>&- ; exec 1>&-; exec 2>&-; cd /tmp; sleep 20&)"
I try to launch another app inside a bash script, but the app seems to exit my script so that the line exec $HOME/bin/sync-iosbeta; does not get executed. I have tried to put it outside the if as well.
if $HOME/bin/BetaBuilder.app/Contents/MacOS/BetaBuilder --args -i "${zip}" -o "${odir}" -u "${ourl}" -r "$PROJECT_FOLDER/README.txt" ; then
echo "Wil sync"
exec $HOME/bin/sync-iosbeta;
fi
echo "This text does not get printed either..";
I have also tried to use open to kick off the app, but then I have issues with passing the arguments, even with --args set.
I am running on Mac OS.
From the exec manual:
If command is specified, it replaces the shell. No new process is created.
Just remove exec and the ";":
if $HOME/bin/BetaBuilder.app/Contents/MacOS/BetaBuilder --args -i "${zip}" -o "${odir}" -u "${ourl}" -r "$PROJECT_FOLDER/README.txt" ; then
echo "Wil sync"
$HOME/bin/sync-iosbeta
fi
echo "This text does not get printed either..";
If sync-iosbeta is not being executed, then may be it hasn't the right permissions. Try:
if $HOME/bin/BetaBuilder.app/Contents/MacOS/BetaBuilder --args -i "${zip}" -o "${odir}" -u "${ourl}" -r "$PROJECT_FOLDER/README.txt" ; then
echo "Wil sync"
/bin/sh $HOME/bin/sync-iosbeta
fi
echo "This text does not get printed either..";
That's the whole point of exec. man bash: If command is specified, it replaces the shell.
just remove exec.