Install multiple packages via bash script with dnf - bash

I'm currently writing a bash script which should install all the software that I need. The process looks promising so far: First, I write a "software-list.txt" file which contains all dependencies for multiple distros. Afterwards bash split these values into an array and reads the corresponding value out of it. Finally the script should combine the distro package manager name (e.g. dnf, if I'm using Fedora Linux) with the operator ("install") with the arguments (which are the software packages).One last info: All variable names which don't appear in the source code, we're defined beforehand
The script looks like this:
One last info: All variable names which don't appear in the source code, were defined beforehand
case "$DISTRO_NAME" in
"Fedora")
PROGRAMM="dnf"
CSV_INDEX=0;;
"Debian")
PROGRAMM="apt-get"
CSV_INDEX=1;;
esac
# Read all required packages
while IFS= read -r line
do
IFS=','
LINE=($line)
if [ $CURR_LINE_INDEX -gt 1 ] && [ $CURR_LINE_INDEX -lt $LINE_COUNT ]
then
ARGUMENTS+="${LINE[$CSV_INDEX]} "
elif [ $CURR_LINE_INDEX -eq $LINE_COUNT ]
then
ARGUMENTS+="${LINE[$CSV_INDEX]}"
fi
CURR_LINE_INDEX=$((CURR_LINE_INDEX+1))
done < "software-list.txt"
# Run installation script
$PROGRAMM $OPERATOR $ARGUMENTS
However, whenever I run the script, the command is correct. But the output is always the same "couldn't find any match for packagex packagey"

I followed Jetchisel's advice and did a shellcheck. How is it now?
#!/bin/bash
case "$DISTRO_NAME" in
"Fedora")
PROGRAMM="dnf"
CSV_INDEX=0;;
"Debian")
PROGRAMM="apt-get"
CSV_INDEX=1;;
esac
# Read all required packages
while IFS= read -r -a line
do
IFS=','
LINE=("${line[#]}")
if [ "$CURR_LINE_INDEX" -gt 1 ] && [ "$CURR_LINE_INDEX" -lt "$LINE_COUNT" ]
then
ARGUMENTS+="${LINE[$CSV_INDEX]} "
elif [ "$CURR_LINE_INDEX" -eq "$LINE_COUNT" ]
then
ARGUMENTS+="${LINE[$CSV_INDEX]}"
fi
CURR_LINE_INDEX=$((CURR_LINE_INDEX+1))
done < "software-list.txt"
# Run installation script
"$PROGRAMM $OPERATOR $ARGUMENTS"

Related

use FTP (only option) to sync files in a directory with a single line command in linux

I need to synchronize files in my computer with server to which I have only FTP access and I would prefer a single line to add to crontab which checks every day that new or updated files are transferred (overwritten).
The question has been asked years ago but no simple answer was forthcoming and I want to know if there are better solutions today than ncftput, wput etc. which do not allow to
ncftpput -R -z -u "USER" -p "PASS" webxx.at /dir/ /source/
is rumored to work, but the -z switch seems "of label" use. My experiments seem to indicate that times are not reliable checked.
Just put this code into a file FtpSync.sh and add this file into your crontab.
You can adjust the parameters in the file. I tried to create "speaking" parameters so that they explain themselves.
A call of this script will either download or upload files (depending on the parameter CopyServerdataToLocal). If you want to do both, simply start the script twice with different parameters (or create two script files).
FtpSync.sh
#!/bin/bash
# Michael Hutter, 20.11.2021
# This Script can be used to synchronize a remote FTP directory and a local directory
HOST='ftp.mywebspace.de'
USER='web1234567f1'
PASS='YourSecretPwd'
SERVERFOLDER='/FolderOnWebspace'
PCFOLDER='/home/michael/ftpsync/MyLocalFolder'
CopyMoreThanOneFileSimultaneously="--parallel=10"
CopyServerdataToLocal=1 # 0=Upload, 1=Download
IgnoreSubdirectories=1
ContinuePartiallyTransmittedFiles=0
DontOverwriteNewerExistingFiles=0 # If this is used ContinuePartiallyTransmittedFiles will not work!
DeleteAdditionalFilesInDestinationDir=0 # Deletes files in DestDir which are not present in SourceDir
RemoveSourceFilesAfterTransfer=0 # Moves the files instead of copying them
ExcludeParams='--exclude-glob .* --exclude-glob .*/' # Exclude (hidden) files and direcories -> starting with a dot
OnlyShowChangesButDontChangeFiles=0 # DryRun mode
OutputAsMuchInfoAsPossible=1 # Verbose mode
################################################################################
if [ $CopyServerdataToLocal -eq 1 ]; then
if [ $OutputAsMuchInfoAsPossible -eq 1 ]; then
echo "Modus=Download"
fi
DIRECTORIES="$SERVERFOLDER $PCFOLDER"
else
if [ $OutputAsMuchInfoAsPossible -eq 1 ]; then
echo "Modus=Upload"
fi
REVERSE='--reverse'
DIRECTORIES="$PCFOLDER $SERVERFOLDER"
fi
if [ $IgnoreSubdirectories -eq 1 ]; then
IGNORESUBDIRS='--no-recursion'
fi
if [ $ContinuePartiallyTransmittedFiles -eq 1 ]; then
CONTINUEFILES='--continue'
fi
if [ $DontOverwriteNewerExistingFiles -eq 1 ]; then
ONLYNEWER='--only-newer'
fi
if [ $DeleteAdditionalFilesInDestinationDir -eq 1 ]; then
DELETE='--delete'
fi
if [ $RemoveSourceFilesAfterTransfer -eq 1 ]; then
REMOVE='--Remove-source-files'
fi
if [ $OnlyShowChangesButDontChangeFiles -eq 1 ]; then
DRYRUN='--dry-run'
fi
if [ $OutputAsMuchInfoAsPossible -eq 1 ]; then
VERBOSE='--verbose'
fi
lftp -f "
open $HOST
user $USER $PASS
lcd $PCFOLDER
mirror $DRYRUN $REVERSE $IGNORESUBDIRS $DELETE $REMOVE $CONTINUEFILES $ONLYNEWER $CopyMoreThanOneFileSimultaneously --use-cache $ExcludeParams $VERBOSE $DIRECTORIES
bye
"

Shell Script compare the values with input parameter

apps="http:git.abc.com";
cluster-ui="http:git.xyz.com";
customer-ui="http:git.xxx.com";
SERVICE=$1;
My requirement is if I pass service name as a 'apps' then I need to clone the $apps url.
Here
if [ $Service -eq apps ]
not think a good approach as my repo url might get increased so more and more loop will come
Any suggestions?
The $ sign assigns the input argument, so we're getting first input if it matches the below variable, so do what you want inside if condition.
#!/bin/bash
apps="http:git.abc.com";
clusterui="http:git.xyz.com";
customerui="http:git.xxx.com";
#SERVICE=$1;
#Store global
repo=''
# if empty parameter is passed
if [ $# -lt 1 ] ; then
echo "Parameters Need"
exit 1
fi;
# for search the correct parameter
if [ $1 = "apps" ]; then
repo=$apps
elif [ $1 = "cluster-ui" ] ; then
repo=$clusterui
elif [ $1 = "customer-ui" ] ; then
repo=$customerui
else
echo "Not found"
fi;
echo $repo
Note just repeat elif [ ] ;then for more entries or think!
how to access run this file like this sh ./file.sh apps just replace apps with yours. make sure you have permission to execute the file if you don't have, give it to permission like below
chmod 766 file
now run the shell script sh ./file.sh clusterui
'Case statement' would suit here more than if ladder

bash script: getting idle time and compare it

Why is the if-compression not comparing the value?
idle_time=exec sudo -u home xprintidle
if [ "$idle_time" -ge 6000 ]
then
echo "hi"
fi
it is not working like that
First of all, I changed to line which you use to execute xprintidle as a different user.
After that I adjusted the if clause, since there was an error as well.
#!/bin/bash
# actually assign the variable
idle_time=$(idle_time=exec sudo -u home xprintidle)
# adapted if clause to actually match (see https://stackoverflow.com/questions/18668556/comparing-numbers-in-bash)
if [ "$idle_time" -gt "6000" ]; then
echo "hi"
fi

Multiparameter in shell script

So, I have a simple script whose only purpose is to help me in my lazyness by allowing me to type less thing when setting acl for someone using blih
#!/bin/sh
if [ "$1" "$2" ]; then
~/.blih.py -u X.X#X.eu repository setacl "$1" "$2" rw
fi
I've named it setacl.sh and set it as an aliases in my .bash_aliases
alias setacl='~/.bash_scripts/setacl.sh'
and yet when I use it, I get the following
setacl Java_epicture_2017 X
/root/.bash_scripts/setacl.sh: 3: [: Java_epicture_2017: unexpected operator
What am I doing wrong?
If you're trying to verify that both arguments are set, write:
if [ -n "$1" ] && [ -n "$2" ]
Or more simply, check the number of arguments passed:
if [ "$#" -eq 2 ]

"[: too many arguments" appears occasionally with pidof

cplane_pid=`pidof hnb_gw.exe`
if [ -z $cplane_pid ]
then
STATUS=`failure`
echo "Cplane hnbgw running $STATUS"
else
STATUS=`success`
echo "Cplane hnbgw running $STATUS"
fi
echo
If there are multiple instances of hnb_gw.exe, pidof will return multiple pids. The -z of [ expects only one pid. One solution might be to use the -s switch of pidof to return only one pid.
You need to Use More Quotes™:
if [ -z "$cplane_pid" ]
Adding set -x before and set +x after the command shows you what it results in. For example:
$ cplane_pid="1 2 3"
$ set -x
$ [ -z $cplane_pid ]
+ '[' -z 1 2 3 ']'
bash: [: too many arguments
In other words, each of the whitespace-separated values in the variable was used as a single parameter. Since -z requires exactly one parameter, this results in a syntax error.
Rather than saving this as a variable, you can simply do
if ! pidof hnb_gw.exe > /dev/null
If the process doesn't exist, it will return 1 ("false").
When you execute
cplane_pid=`pidof hnb_gw.exe`
then cplane_pid can contain more (space separated) items.
So the expansion in
if [ -z $cplane_pid ]
will become
if [ -z firstPid secondPid etc ]
and that is your error "[: too many arguments"
You can solve this with quoting the variable (you should do this ALWAYS in shell)
if [ -z "$cplane_pid" ]
or use [[ (if it's installed on your system), which is better in many ways. For instance you don't need to quote variable :)
if [[ -z $cplane_pid ]]
is the same as
if [[ -z "$cplane_pid" ]]
For testing purposes (and erros like this) use -x hasbang bash option
#!/bin/bash -x
or use debug sections
-- normal code --
set -x # debug section starts here
[ -z $cplane_pid ] && echo zero
eval something
set +x # debug section ends here
-- normal code --
also you can call the script
/bin/bash -x yourScript.sh
pidof can return more than one pid, in these cases, your test will get too many arguments.

Resources