Bash script to create virtual clusters isn't working - linux

I am trying to create a script to create virtual clusters on my virtual machine which is a CentOS 7 minimal.
I got a script named cluster
#!/bin/bash
function vc
{
echo
echo -n "Enter project name: "
read platform_name
echo
echo -n "web extension: "
read web_extension
echo
echo -e "The following website will be created"
echo -e "\e[32m Platform:\e[0m\t${platform_name}"
echo -e "\e[32m Extension:\e[0m\t${web_extension}"
echo -e "\e[32m Full URL:\e[0m\t http://www.${platform_name}.${web_extension}"
echo
echo -e "Do you wish to proceed? [Y/n]"
read -p "Are you sure? " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo
echo -e "\e[32m Creating platform \e[0m\t"
else
echo
echo -e "\e[32m Not creating platform \e[0m\t"
fi
}
if [ -n "$(type -t $FUNCTION_NAME)" ] && [ "$(type -t $FUNCTION_NAME)" =
function ];
then $FUNCTION_NAME $2; else help; fi
Then as far as I understood I just have to make it executable
chmod +x cluster
And after this I should make a syslink for it ln -s cluster /bin/cluster
And now I should normally be able to just typ cluster vc in the terminal and it should execute the script but it keeps giving me "command cluster not found"
Am I doing something obviously wrong? Or do I need to use another chmod on it so I can run this?

Symbolic link targets are resolved relative the the symlink location. In your case that means, if you run /bin/cluster it looks for a file named cluster (the target) in the /bin/directory. Either provide a relative path which points to your file or link to an absolute path: ln -s /path/to/cluster /bin/cluster.
Also make sure that the target location is readable and executable by whomever executes the symlink.

Related

Transfer files using lftp in bash script

I have server A test-lx, and server B test2-lx, I want to transfer files from server A to server B.
While transfering the files i'll need to create a driectory only if it's not exist, how can i check if a directory exist during the lftp conenction? How can i out several files in one command instead of doing this in 2 lines.
Is there an option to use find -maxdepth 1 -name DirName
Here is my code:
lftp -u drop-up,1Q2w3e4R ftp://ta1bbn01:21 << EOF
cd $desFolder
mkdir test
cd test
put $srcFil
put $srcFile
bye
EOF
Simple way with ftp:
#!/bin/bash
ftp -inv ip << EOF
user username password
cd /home/xxx/xxx/what/you/want/
put what_you_want_to_upload
bye
EOF
With lftp:
#!/bin/bash
lftp -u username,password ip << EOF
cd /home/xxx/xxx/what/you/want/
put what_you_want_to_upload
bye
EOF
From lftp manual:
-u <user>[,<pass>] use the user/password for authentication
You can use mkdir for create a directory. And you can use put command several time like this:
put what_you_want_to_upload
put what_you_want_to_upload2
put what_you_want_to_upload3
And you can close connection with bye
You can check folder is exist or not like this:
#!/bin/bash
checkfolder=$(lftp -c "open -u user,pass ip; ls /home/test1/test1231")
if [ "$checkfolder" == "" ];
then
echo "folder does not exist"
else
echo "folder exist"
fi
From lftp manual:
-c <cmd> execute the commands and exit
And you can open another connection for put some files.
I don't know how to check folder is exist or not with one connection, but I can do that like this. Maybe you can find better solution:
#!/bin/bash
checkfolder=$(lftp -c "open -u user,pass ip; ls /home/test1/test2")
if [ "$checkfolder" == "" ];
then
lftp -u user,pass ip << EOF
mkdir test2
cd test2
put testfile.txt
bye
EOF
else
echo "The directory already exists - exiting"
fi
I used the same basic coding outline as phe however I found that using ls /foldername will output "folder does not exist" if the folder is empty. To solve this I use
#!/bin/bash
checkfolder=$(lftp -c "open -u user,pass ip; ls | grep /test1231")
if [ "$checkfolder" == "" ];
then
echo "folder does not exist"
else
echo "folder exists"
fi
Please note this only works if the folder is in the root directory. For sub directories in a folder the following should work.
#!/bin/bash
checkfolder=$(lftp -c "open -u user,pass ip; find | grep home/test1/test1231")
if [ "$checkfolder" == "" ];
then
echo "folder does not exist"
else
echo "folder exists"
fi
First prepare credentials record into ~/.netrc file as:
machine site-url-here
login user-login-here
password user-password-here
so you don't have to expose your password on the command line to use this in script.
Then call:
lftp -e "lftp-command-here" ftps://user-login-here#site-url-here/initial-folder-here/`
In my case I run mget -c * lftp command for getting all logs from java spring boot application running linux app instance at azure infrastructure.
Of course you can put your commands separated by semicolon there.

Bash script creating hybrid iso generates “unexpected end of file”

I've created a simple bash script that creates a hybrid iso. But when I try to run it, I get the output:
hybridiso.sh: line 58: syntax error: unexpected end of file.
I've checked the script and tried to makes changes to it but I still get the same output. What's wrong with the script?
#!/bin/bash
##Sanity Cheks##
if [ "$(whoami)" != root ]; then
echo "You must be root to execute this script."
fi
if [ ! -x /usr/bin/xorriso ]; then
echo "xorriso is not installed. Run 'apt-get install xorriso' to install it."
exit 1
fi
if [ ! -x /usr/bin/live-build ]; then
echo "live-build is not installed. Run 'apt-get install live-build' to install it."
exit 1
fi
if [ ! -x /usr/bin/syslinux ]; then
echo "syslinux is not insatlled. Run 'apt-get install syslinux' to install it."
exit 1
fi
if [ ! -x /usr/bin/mksquashfs ]; then
echo "squashfs-tools is not installed. Run 'apt-get install squashfs-tools' to install it."
exit 1
fi
###############
mkdir $PWD/hybridiso
cd hybridiso
mkdir -p binary/live && mkdir -p binary/isolinux
read -e -p "Enter local file path for linux kernel " kernel
read -e -p "Enter local file path for initrd " initrd
cp $kernel binary/live/ && cp $initrd binary/live/
#mksquashfs chroot binary/live/filesystem.squashfs -comp xz -e boot
cp /usr/lib/syslinux/isolinux.bin binary/isolinux/
cp /usr/lib/syslinux/menu.c32 binary/isolinux/
while true; do
read -p "Do you have an isolinux.cfg? " resp
if [ $resp -eq no ]; then
echo "You need to create a valid isolinux.cfg file!"
echo "Creating example file $PWD/isolinux.cfg.example"
echo -e "ui menu.c32\nprompt 0\nmenu title Boot Menu\ntimeout 300\n\n\nlabel live-amd64\n menu label ^Live (amd64)\n menu default\n linux /live/linux\n append initrd=/live/initrd.gz boot=live persistence quiet\n\n\nlabel live-amd64-failsafe\n menu label ^Live (amd64 failsafe)\nlinux /live/linux\nappend initrd=/live/initrd.gz boot=live persistence config memtest noapic noapm nodma nomce nolapic nomodest nosmp nosplash vga=normal\n\n\nendtext" >> isolinux.cfg.example
exit 1
elif [ $resp -eq yes ]; then
break
else
"Put only in yes or no"
fi
read -e -p "Enter local file path for isolinux.cfg" isolinux
cp $isolinux binary/isolinux/
xorriso -as mkisofs -r -J -joliet-long -l -cache-inodes -isohybrid-mbr /usr/lib/syslinux/isohdpfx.bin -partition_offset 16 -A "Debian Live" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o kiosk.iso binary
echo "Script is succesfull!"
exit 0
You haven't terminated the while loop with done anywhere; Add done at the appropriate location.

Bash script output not going to stdout

I have a build process, kicked off by Make, that executes a lot of child scripts.
A couple of these child scripts require root privileges, so instead of running everything as root, or everything as sudo, I'm trying to only execute the scripts that need to be as root, as root.
I'm accomplishing this like so:
execute_as_user() {
su "$1" -s /bin/bash -c "$2;exit \$?"
}
Arg $1 is the user to run the script as, arg $2 is the script.
Arg $1 is either root (gotten with: $(whoami) since everything is under sudo), or the current user's account (gotten with: $(logname))
The entire build is kicked off as:
sudo make all
Sample from the Makefile:
LOG="runtime.log"
ROTATE_LOG:=$(shell bash ./scripts/utils/rotate_log.sh)
system:
/bin/bash -c "time ./scripts/system.sh 2>&1 | tee ${LOG}"
My problem is... none of the child scripts are printing output to stdout. I believe it to be some sort of issue with an almost recursive call of su root... but I'm unsure. From my understanding, these scripts should already be outputting to stdout, so perhaps I'm mistaken where the output is going?
To be clear, I'm seeing no output in either the logfile nor displaying to the terminal (stdout).
Updating for clarity:
Previously, I just ran all the scripts either with sudo or just as the logged in user... which with my makefile above, would print to the terminal (stdout) and logfile. Adding the execute_as_user() function is where the issue cropped up. The scripts execute and build the project... just no display "that it's working" and no logs.
UPDATE
Here is some snippets:
system.sh snippet:
execute_script() {
echo "Executing as user $3: $2"
RETURN=$(execute_as_user $3 ${SYSTEM_SCRIPTS}/$2)
if [ ${RETURN} -ne ${OK} ]
then
error $1 $2 ${RETURN}
fi
}
build_package() {
local RETURN=0
case "$1" in
system)
declare -a scripts=(\
"rootfs.sh" \
"base_files.sh" \
"busybox.sh" \
"iana-etc.sh" \
"kernel.sh" \
"firmware.sh" \
"bootscripts.sh" \
"network.sh" \
"dropbear.sh" \
"wireless_tools.sh" \
"e2fsprogs.sh" \
"shared_libs.sh"
)
for SCRIPT_NAME in "${scripts[#]}"; do
execute_script $1 ${SCRIPT_NAME} $(logname)
echo ""
echo -n "${SCRIPT_NAME}"
show_status ${OK}
echo ""
done
# finalize base system
echo ""
echo "Finalizing base system"
execute_script $1 "finalize.sh" $(whoami)
echo ""
echo -n "finalize.sh"
show_status ${OK}
echo ""
# package into tarball
echo ""
echo "Packing base system"
execute_script $1 "archive.sh" $(whoami)
echo ""
echo -n "archive.sh"
show_status ${OK}
echo ""
echo ""
echo -n "Build System: "
show_status ${OK}
;;
*)
echo "$1 is not supported!"
exit 1
esac
}
sample child script executed by system.sh
cd ${CLFS_SOURCES}/
tar -xvjf ${PKG_NAME}-${PKG_VERSION}.tar.bz2
cd ${CLFS_SOURCES}/${PKG_NAME}-${PKG_VERSION}/
make distclean
RESPONSE=$?
if [ ${RESPONSE} -ne 0 ]
then
pkg_error ${RESPONSE}
exit ${RESPONSE}
fi
ARCH="${CLFS_ARCH}" make defconfig
RESPONSE=$?
if [ ${RESPONSE} -ne 0 ]
then
pkg_error ${RESPONSE}
exit ${RESPONSE}
fi
# fixup some bugs with musl-libc
sed -i 's/\(CONFIG_\)\(.*\)\(INETD\)\(.*\)=y/# \1\2\3\4 is not set/g' .config
sed -i 's/\(CONFIG_IFPLUGD\)=y/# \1 is not set/' .config
etc...
Here's the entire system.sh script:
https://github.com/SnakeDoc/LiLi/blob/master/scripts/system.sh
(i know the project is messy... it's a learn-as-you-go style project)
Previously, I just ran all the scripts either with sudo or just as the
logged in user... which with my makefile above, would print to the
terminal (stdout) and logfile. Adding the execute_as_user() function
is where the issue cropped up. The scripts execute and build the
project... just no display "that it's working" and no logs.
Just a guess, but you're probably not calling your function or not calling it properly:
execute_as_user() {
su "$1" -s /bin/bash -c "$2;exit \$?"
}
execute_as_user "$#"
I also noticed that you're not passing any argument to the script at all. Is this meant?
./scripts/system.sh ???

check if file exists on remote host with ssh

I would like to check if a certain file exists on the remote host.
I tried this:
$ if [ ssh user#localhost -p 19999 -e /home/user/Dropbox/path/Research_and_Development/Puffer_and_Traps/Repeaters_Network/UBC_LOGS/log1349544129.tar.bz2 ] then echo "okidoke"; else "not okay!" fi
-sh: syntax error: unexpected "else" (expecting "then")
In addition to the answers above, there's the shorthand way to do it:
ssh -q $HOST [[ -f $FILE_PATH ]] && echo "File exists" || echo "File does not exist";
-q is quiet mode, it will suppress warnings and messages.
As #Mat mentioned, one advantage of testing like this is that you can easily swap out the -f for any test operator you like: -nt, -d, -s etc...
Test Operators: http://tldp.org/LDP/abs/html/fto.html
Here is a simple approach:
#!/bin/bash
USE_IP='-o StrictHostKeyChecking=no username#192.168.1.2'
FILE_NAME=/home/user/file.txt
SSH_PASS='sshpass -p password-for-remote-machine'
if $SSH_PASS ssh $USE_IP stat $FILE_NAME \> /dev/null 2\>\&1
then
echo "File exists"
else
echo "File does not exist"
fi
You need to install sshpass on your machine to work it.
Can't get much simpler than this :)
ssh host "test -e /path/to/file"
if [ $? -eq 0 ]; then
# your file exists
fi
As suggested by dimo414, this can be collapsed to:
if ssh host "test -e /path/to/file"; then
# your file exists
fi
one line, proper quoting
ssh remote_host test -f "/path/to/file" && echo found || echo not found
You're missing ;s. The general syntax if you put it all in one line would be:
if thing ; then ... ; else ... ; fi
The thing can be pretty much anything that returns an exit code. The then branch is taken if that thing returns 0, the else branch otherwise.
[ isn't syntax, it's the test program (check out ls /bin/[, it actually exists, man test for the docs – although can also have a built-in version with different/additional features.) which is used to test various common conditions on files and variables. (Note that [[ on the other hand is syntax and is handled by your shell, if it supports it).
For your case, you don't want to use test directly, you want to test something on the remote host. So try something like:
if ssh user#host test -e "$file" ; then ... ; else ... ; fi
Test if a file exists:
HOST="example.com"
FILE="/path/to/file"
if ssh $HOST "test -e $FILE"; then
echo "File exists."
else
echo "File does not exist."
fi
And the opposite, test if a file does not exist:
HOST="example.com"
FILE="/path/to/file"
if ! ssh $HOST "test -e $FILE"; then
echo "File does not exist."
else
echo "File exists."
fi
ssh -q $HOST [[ -f $FILE_PATH ]] && echo "File exists"
The above will run the echo command on the machine you're running the ssh command from. To get the remote server to run the command:
ssh -q $HOST "[[ ! -f $FILE_PATH ]] && touch $FILE_PATH"
Silent check if file exist and perform if not
if ! ssh $USER#$HOST "test -e file.txt" 2> /dev/null; then
echo "File not exist"
fi
You can specify the shell to be used by the remote host locally.
echo 'echo "Bash version: ${BASH_VERSION}"' | ssh -q localhost bash
And be careful to (single-)quote the variables you wish to be expanded by the remote host; otherwise variable expansion will be done by your local shell!
# example for local / remote variable expansion
{
echo "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'" |
ssh -q localhost bash
echo '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"' |
ssh -q localhost bash
}
So, to check if a certain file exists on the remote host you can do the following:
host='localhost' # localhost as test case
file='~/.bash_history'
if `echo 'test -f '"${file}"' && exit 0 || exit 1' | ssh -q "${host}" sh`; then
#if `echo '[[ -f '"${file}"' ]] && exit 0 || exit 1' | ssh -q "${host}" bash`; then
echo exists
else
echo does not exist
fi
I wanted also to check if a remote file exist but with RSH. I have tried the previous solutions but they didn't work with RSH.
Finally, I did I short function which works fine:
function existRemoteFile ()
{
REMOTE=$1
FILE=$2
RESULT=$(rsh -l user $REMOTE "test -e $FILE && echo \"0\" || echo \"1\"")
if [ $RESULT -eq 0 ]
then
return 0
else
return 1
fi
}
On CentOS machine, the oneliner bash that worked for me was:
if ssh <servername> "stat <filename> > /dev/null 2>&1"; then echo "file exists"; else echo "file doesnt exits"; fi
It needed I/O redirection (as the top answer) as well as quotes around the command to be run on remote.
This also works :
if ssh user#ip "[ -s /path/file_name ]" ;then
status=RECEIVED ;
else
status=MISSING ;
fi
#its simple
if [[ "`ssh -q user#hostname ls /dir/filename.abc 2>dev/null`" == "/dir/filename.abc" ]]
then
echo "file exists"
else
echo "file not exists"
fi

Consuming bandwidth

I know how to write a basic bash script which uses wget to download a file, but how do I run this in an endless loop to download the specified file, delete it when the download is complete, then download it again.
you're looking for
while :
do
wget -O - -q "http://some.url/" > /dev/null
done
this will not save the file, not output useless info, and dump the contents over and over again in /dev/null
edit to just consume bandwidth, use ping -f or ping -f -s 65507
If your goal is to max out your bandwidth, especially for the purposes of benchmarking, use iperf. You run iperf on your server and client, and it will test your bandwidth using the protocol and parameters you specify. It can test one-way or two-way throughput and can optionally try to achieve a "target" bandwidth utilization (i.e. 3Mbps).
Everything is possible with programming. :)
If you want to try and max out your internet bandwidth, you could start many many processes of wget and let them download some big disk image files at the same time, while at the same time sending some huge files back to some server.
The details are left for the implementation, but this is one method to max out your bandwidth.
In case you want to consume network bandwidth, you'll need another computer. Then from computer A, IP 192.168.0.1, listen on a port (e.g. 12345).
$ netcat -l -p 12345
Then, from the other computer, send data to it.
$ netcat 192.168.0.1 12345 < /dev/zero
I perfer to use curl to wget. it is more editable. here is an excrpt from a bash script i wrote which checks the SVN version, and then gives the user a choice to download stable or latest. It then parses out the file, separating the "user settings" from the rest of the script.
svnrev=`curl -s -m10 mythicallibrarian.googlecode.com/svn/trunk/| grep -m1 Revision | sed s/"<html><head><title>mythicallibrarian - "/""/g| sed s/": \/trunk<\/title><\/head>"/""/g`
if ! which librarian-notify-send>/dev/null && test "$LinuxDep" = "1"; then
dialog --title "librarian-notify-send" --yesno "install librarian-notify-send script for Desktop notifications?" 8 25
test $? = 0 && DownloadLNS=1 || DownloadLNS=0
if [ "$DownloadLNS" = "1" ]; then
curl "http://mythicallibrarian.googlecode.com/files/librarian-notify-send">"/usr/local/bin/librarian-notify-send"
sudo chmod +x /usr/local/bin/librarian-notify-send
fi
fi
if [ ! -f "./librarian" ]; then
DownloadML=Stable
echo "Stable `date`">./lastupdated
else
lastupdated="`cat ./lastupdated`"
DownloadML=$(dialog --title "Version and Build options" --menu "Download an update first then Build mythicalLibrarian" 10 70 15 "Latest" "Download and switch to SVN $svnrev" "Stable" "Download and switch to last stable version" "Build" "using: $lastupdated" 2>&1 >/dev/tty)
if [ "$?" = "1" ]; then
clear
echo "mythicalLibrarian was not updated."
echo "Please re-run mythicalSetup."
echo "Done."
exit 1
fi
fi
clear
if [ "$DownloadML" = "Stable" ]; then
echo "Stable "`date`>"./lastupdated"
test -f ./mythicalLibrarian.sh && rm -f mythicalLibrarian.sh
curl "http://mythicallibrarian.googlecode.com/files/mythicalLibrarian">"./mythicalLibrarian.sh"
cat "./mythicalLibrarian.sh"| sed s/' '/'\\t'/g |sed s/'\\'/'\\\\'/g >"./mythicalLibrarian1" #sed s/"\\"/"\\\\"/g |
rm ./mythicalLibrarian.sh
mv ./mythicalLibrarian1 ./mythicalLibrarian.sh
parsing="Stand-by Parsing mythicalLibrarian"
startwrite=0
test -f ./librarian && rm -f ./librarian
echo -e 'mythicalVersion="'"`cat ./lastupdated`"'"'>>./librarian
while read line
do
test "$line" = "########################## USER JOBS############################" && let startwrite=$startwrite+1
if [ $startwrite = 2 ]; then
clear
parsing="$parsing""."
test "$parsing" = "Stand-by Parsing mythicalLibrarian......." && parsing="Stand-by Parsing mythicalLibrarian"
echo $parsing
echo -e "$line" >> ./librarian
fi
done <./mythicalLibrarian.sh
clear
echo "Parsing mythicalLibrarian completed!"
echo "Removing old and downloading new version of mythicalSetup..."
test -f ./mythicalSetup.sh && rm -f ./mythicalSetup.sh
curl "http://mythicallibrarian.googlecode.com/files/mythicalSetup.sh">"./mythicalSetup.sh"
chmod +x "./mythicalSetup.sh"
./mythicalSetup.sh
exit 0
fi
if [ "$DownloadML" = "Latest" ]; then
svnrev=`curl -s mythicallibrarian.googlecode.com/svn/trunk/| grep -m1 Revision | sed s/"<html><head><title>mythicallibrarian - "/""/g| sed s/": \/trunk<\/title><\/head>"/""/g`
echo "$svnrev "`date`>"./lastupdated"
test -f ./mythicalLibrarian.sh && rm -f mythicalLibrarian.sh
curl "http://mythicallibrarian.googlecode.com/svn/trunk/mythicalLibrarian">"./mythicalLibrarian.sh"
cat "./mythicalLibrarian.sh"| sed s/' '/'\\t'/g |sed s/'\\'/'\\\\'/g >"./mythicalLibrarian1" #sed s/"\\"/"\\\\"/g |
rm ./mythicalLibrarian.sh
mv ./mythicalLibrarian1 ./mythicalLibrarian.sh
parsing="Stand-by Parsing mythicalLibrarian"
startwrite=0
test -f ./librarian && rm -f ./librarian
echo -e 'mythicalVersion="'"`cat ./lastupdated`"'"'>>./librarian
while read line
do
test "$line" = "########################## USER JOBS############################" && let startwrite=$startwrite+1
if [ $startwrite = 2 ]; then
clear
parsing="$parsing""."
test "$parsing" = "Stand-by Parsing mythicalLibrarian......." && parsing="Stand-by Parsing mythicalLibrarian"
echo $parsing
echo -e "$line" >> ./librarian
fi
done <./mythicalLibrarian.sh
clear
echo "Parsing mythicalLibrarian completed!"
echo "Removing old and downloading new version of mythicalSetup..."
test -f ./mythicalSetup.sh && rm -f ./mythicalSetup.sh
curl "http://mythicallibrarian.googlecode.com/svn/trunk/mythicalSetup.sh">"./mythicalSetup.sh"
chmod +x "./mythicalSetup.sh"
./mythicalSetup.sh
exit 0
fi
EDIT: NEVERMIND I THOUGHT YOU WERE SAYING IT WAS DOWNLOADING IN AN ENDLESS LOOP

Resources