This question already has answers here:
bash file returns unexpected token `$'do\r''
(7 answers)
Closed 3 years ago.
I'm developing an opensource program , I need to find out the error here.
This is a linux-meant BASH script.
I can't figure out what's wrong with this code:
#!/usr/bin/env bash
declare -a dependenciesList=(
"element2"
"element3"
"element4"
)
#check des dependences dans le systeme actuel:
#____________procedure de verification de l'existance de la dependance
exists ()
{
command -v "$1" >/dev/null 2>&1
}
#____________procedure de l'installation de la dependance
install ()
{
echo "[INSTALL] '$1' installation started"
apt-get install "$1"
}
#____________procedure coeur
for i in "${dependenciesList[#]}"
do
echo "[CHECK] Verification de l'existance de la dependence : $i"
# or do whatever with individual element of the array
if exists "$i"; then
echo " $i [OK]"
else
echo "[CHECK][ERROR][CRITICAL] Le systeme n'a pas $i ,appel a la procedure d'installation "
install "$i"
fi
done
The code blocks at the function exits always , and returns this error log:
./linux.dependencies.check.bash: syntax error near unexpected token `$'\r''
'/linux.dependencies.check.bash: `exists ()
You saved your script with Windows line endings (\r\n instead of just \n), which is confusing the Linux program bash. Run dos2unix on the script to fix it.
Related
I'm trying to make a bash script that goes in the .gitmodules file, gets the path and branch of each submodule then goes where the submodule is located and git checkout to the right branch. BUT the git commands doesn't work well when I run the script but work well when I enter them manully in the terminal.
Keep getting stuff like :
-> fatal not a git repository (or any of the parent directories): .git
(I then added git init in the while loop)
-> fatal : you are on a branch yet to be born
Can you tell me what i'm missing here plz ?
#!/bin/bash
sed -n '/path/p' .gitmodules > tampon01.txt #selectionne uniquement les ligne contenant path
sed -n '/branch/p' .gitmodules > tampon02.txt #selectionne uniquement les ligne contenant path
cut -d = -f 2- tampon01.txt > pathlist.txt #selectionne uniquement les champs de caractères après le "=") pour les path
cut -d = -f 2- tampon02.txt > branchlist.txt #selectionne uniquement les champs de caractères après le "=") pour les branch
let "i=1"
Pnb_lignes=$(sed -n '$=' pathlist.txt)
Bnb_lignes=$(sed -n '$=' branchlist.txt)
echo $Pnb_lignes "path trouvées"
echo $Bnb_lignes "branch trouvées"
#while [ $i < $nb_lignes ]
#if [$Pnb_lignes -le $Bnb_lignes] #test pour trouver le minimum entre le nb de lignes trouvée dans chaque fichier
if [ 5 -le 2 ] #test pour trouver le minimum entre le nb de lignes trouvée dans chaque fichier
then
let "nb_lignes = Pnb_lignes"
else
let "nb_lignes = Bnb_lignes"
fi
echo $nb_lignes "actions a realiser"
while (($i < $nb_lignes))
do
#pa= $(sed -n "$i"p tampon02.txt) #retourne la ligne i
pa= sed -n "$i"p pathlist.txt
br= sed -n "$i"p branchlist.txt
#echo $pa "xxxx"
cd $pa
git init
git checkout $br
cd /mnt/c/_D/Devel/taoSet
echo ".............................."
let "i = $i +2"
done
echo $i "actions realisees"
#rm -v tampon01.txt tampon02.txt branchlist.txt pathlist.txt
In bash, there cannot be any spaces around the = sign in an assignment statement.
In a terminal, it may be re-using the values from previously assigned variables.
While in a bash script, since old / global variables are not accessible by default, it may assign null values or fail for incorrectly written commands and proceed ahead.
This is a plausible reason that you get different behaviours in both approaches.
The command substitution seems to be missing, leading to the $pa and $br variables to be undefined in these lines:
pa= sed -n "$i"p pathlist.txt
br= sed -n "$i"p branchlist.txt
It should be
pa=$(sed -n "$i"p pathlist.txt)
br=$(sed -n "$i"p branchlist.txt)
Other things could be broken as well, haven't checked thoroughly.
In the code below I was expecting an output like this:
Transmission_Downloads/The.Last.Man.On.Earth.S02E04.HDTV.x264-KILLERS[ettv]/Torrent-Downloaded-from-ExtraTorrent.cc.txt
Transmission_Downloads/Fargo.S02E01.HDTV.x264-KILLERS[ettv]/Torrent-Downloaded-from-ExtraTorrent.cc.txt
Transmission_Downloads/Nightwish - Showtime Storytime (2013) 1080p 5.1/SEMEAR.txt
But what I do got was this
Transmission_Downloads/The.Last.Man.On.Earth.S02E04.HDTV.x264-KILLERS[ettv]/Torrent-Downloaded-from-ExtraTorrent.cc.txt
Transmission_Downloads/Fargo.S02E01.HDTV.x264-KILLERS[ettv]/Torrent-Downloaded-from-ExtraTorrent.cc.txt
Transmission_Downloads/Nightwish
-
Showtime
Storytime
(2013)
1080p
5.1/SEMEAR.txt
What should I do for my shell script parse blank spaces on file and folder names correctly? Thanks!
#!/bin/bash
#opcao -s nao mostra o texto na tela
echo "Digite sua senha"
read -s answer
root_folder="/home/pi/"
user="pi"
server="*****"
local_folder="/home/dellcloud2"
#Colocar aqui os paths dos arquivos que deseja puxar
array=(
"Transmission_Downloads/The.Last.Man.On.Earth.S02E04.HDTV.x264-KILLERS[ettv]/Torrent-Downloaded-from-ExtraTorrent.cc.txt"
"Transmission_Downloads/Fargo.S02E01.HDTV.x264-KILLERS[ettv]/Torrent-Downloaded-from-ExtraTorrent.cc.txt"
"Transmission_Downloads/Nightwish - Showtime Storytime (2013) 1080p 5.1/SEMEAR.txt"
)
for i in ${array[#]}; do
#sshpass -p $answer rsync -aP $user#$server:$root_folder$i $local_folder
echo $i
done
You need to use "${array[#]}" to preserve white space. The quotes around the array plus the wildcard # together enable this.
This also works with positional parameters, i.e. "$#" gives you an array of the command line arguments, properly quoted as they were given.
Can someone help and tell me why this isn't working?
I have checked the script and solved some problems but it still doesn't works fine and I can't find the mistake.
#!/bin/bash
#variabelen
IP="192.168.0."
array=($#)
#functies
What's wrong with the array? My linux told me that there is a syntax error on line 12 so with that array but he doesn't tell me what.
function Sorteer(){
array=($(printf '%s\n' "$#"|sort -nu))
for i in ${array[#]};do
ping -c -1 "IP"$i
done
}
function Telbij(){
# given number $i +200
b=$(( $i + 200 ))
if (( b > 255 ))
then
echo "Neem kleiner getal";
else
ping -c 1 "IP"$b;
fi
}
function XXYY() {
#ping 65-68 = ping 65 66 67 68
start=${1%-*}
end=${1#*-}
for ((i=start;i<=end;i++));do
ping -c 1 "$IP"$i
done
}
The mistake is in the if else function: http://prntscr.com/7gr8yf
But I don't know what that means: "The mentioned parser error was in this else clause."
if [ "$#" -eq 0 ]; then
echo "Er moet minimaal 1 parameter worden meegegeven "
exit 0
else
case
-h -help ) echo "Geef de laatste cijfers van het IP-adres van de pc's om te testen.";;
XX-YY ) XXYY;;
-t ) Telbij;;
- sort ) Sorteer;;
esac
fi
done
Don't know what's specifically not working but,
in Sorteer function you should double quote array expansions to avoid re-splitting elements.
Try change to following:
function Sorteer(){
array=($(printf '%s\n' "$#"|sort -nu))
for i in "${array[#]}";do
ping -c -1 "IP"$i
done
}
Now your case operator should be like:
case $some_value in
-help ) echo "Geef de laatste cijfers van het IP-adres van de pc's om te testen.";;
XX-YY ) XXYY;;
-t ) Telbij;;
-sort ) Sorteer;;
esac
This will fix your if issue as well
I have a linux server running, which I back up every day.
The backup script works like a charm, but I would like some feedback on completion with or without errors.
#!/bin/bash
# Hier gaan we zoeken naar alle mappen en onderliggende mappen in de LinuxKJ server.
find /var/www -maxdepth 1 -mindepth 1 -print0 | while read -d $'\0' foldername
do
# Hier gaan we alle mappen in zipjes comprimeren en overzetten naar een andere locatie. Overigens laat hij _Inactief eruit.
fatsoenlijkPad=$(echo $foldername)
tar --exclude='/var/www/_Inactief' -zcvpf /mediabak/winboxbak/"${fatsoenlijkPad##*/}".tar.gz "$fatsoenlijkPad"
# Hier gaan we kijken of de functie hierboven een succes return (Succes = 0) (Fout = 1,2,3,4, etc)
if ( $? == 0 ) then
Mailtext=$(echo "Backup succesvol.")
else
Mailtext=$(echo "Backup failed.")
fi
done
# Hier gaan we mailen wat de functie heeft gereturned
mail -s "Linux backup" "example#example.com"
$Mailtext
./backupscript.sh: line 9: 141: command not found
Can anyone help me to fix this issue?
In bash square brackets are used. Hence change
if ( $? == 0 ) then
to
if [ $? == 0 ]; then
Edit: Change
mail -s "Linux backup" "example#example.com"
$Mailtext
to
echo $Mailtext | mail -s "Linux backup" example#example.com
To verify that your are able to send and receive a mail, try to send a mail with dummy text as below.
echo "Testing Mail" | mail -s "Linux backup" example#example.com
As commented, your variable assignement for Mailtext are inefficient (it works, but it has no sense to use an echo command to assign a text value).
As for your email sending, your mail command invocation should be :
echo $Mailtext | mail -s "Linux backup" "example#example.com"
I have to make a phone_book in shell (bash)..
Here's what the program should do.
Add a number : You ask for the name and the number.If it doesn't exist already ( verification) then add a file in the same directory called $name and contain 1 line: the number.
Obtain the liste of names already saved.
Look for a number by giving his name ( we have to verify also if it exists or not.
modify a number ( verification also)
looking for a name by giving his number.( verification).
I Think that we have to use case I looked in the net, but I have difficulties with Shell.
Hope you helps me guys. Don't hesitate to ask me questions. Thanks
#!/bin/bash
echo " 1)Ajouter une fiche
2)Obtenir la liste des noms déjà enregistrés
3)Chercher un numéro de téléphone
4)Modifier un numero de téléphone
5)Rechercher un nom"
read x
case $x in
1)
echo " Tapez le nom à rajouter"
read nom
touch $nom
;;
UPDATE:
I have almost finished it, I have a problem with the 5) when i type an existant number , it always telling me that it doesn't exist..
Feel free to make some improvement in my code :)
#!/bin/bash
echo " 1)Ajouter une fiche
2)Obtenir la liste des noms déjà enregistrés
3)Chercher un numéro de téléphone
4)Modifier un numero de téléphone
5)Rechercher un nom"
read x
case $x in
1)
echo " Tapez le nom à rajouter"
read nom
while [ -f $nom ]; do
echo "Le fichier existe déjà"
echo " Tapez le nom à rajouter"
read nom
done
touch $nom
echo " Maintenant, tapez le numero de la personne à rajouter"
read numero
echo $numero >> $nom
;;
2)
echo $(ls);;
3)
echo " Tapez le nom de la personne que vous recherchez"
read nomrech
while [ ! -f $nomrech ]; do
echo "Le fichier n'existe pas"
read nomrech
done
cat $nomrech
;;
4)
echo "Tapez le nom d'un contacte à modifier"
read nommodif
while [ ! -f $nommodif ]; do
echo "Le fichier n'existe pas"
read nommodif
done
echo "Tapez le nouveau numéro à modifier"
read nouvnum
echo $nouvnum > $nommodif
;;
5)
echo " Tapez le numero de la personne que vous cherchez"
read numchercher
while ! grep -i "$numchercher" * ; do
echo "ce numero n'existe pas "
read nomchercher
done
grep $numchercher *
;;
esac
First of all, you need to think about how you will actually store the datas. Then, try to associate an action to each items:
Create a file named by the input containing one single line
browse the folder and extract all the filenames in that directory
find a file in a directory, given its name
modify the content of a file given its name (you can trash the content of the file at that point)
Find a filename given a pattern
So basically, I think you can manage to do the assignment with the following commands: cat, find, *, grep and that's it!
Update:
For your last question (5th point), it seems to me that your code is really complicated. Have a look on this sample:
$ echo 0123456789 > john
$ echo 0987654321 > bob
$ grep 0987654321 *
bob:0987654321
$ grep jfkljlfds *
$ echo $?
1
$ grep 0123456789 *
john:0123456789
$ echo $?
0
$ false
$ echo $?
1
$ false || echo "oops that one didn't work"
oops that one didn't work
Now I think you have everything you need to keep going.
$? is the return code from previous command. If you have a look on man grep (1):
EXIT STATUS
The exit status is 0 if selected lines are found, and 1 if not found. If an error occurred the exit status is 2. (Note: POSIX error handling
code should check for '2' or greater.)
So basically, the trick using the or operator (||) is used to display an error only if the left part returned false.
I suppose read name; grep $name * || echo "$name was not found" would do the trick.
And by the way, you're often asking arguments twice (after checking). You shouldn't need that. The variable still exists after your test.