Linux select statement with extra options - linux

I`m busy with writing a script that can download some files from an FTP and i want a select statement to give the directorys in the ftp sub directory. But also to give a option download all this should happen # $DNAtype at the bottum. Someone any ideas?
My code is:(sorry for the dutch comment)
#!/bin/bash/
#16-03-2012
#Sander van der Zeeuw s1040176
#Variabele om de ftp aan te kunnen roepen
var='ftp://ftp.ensembl.org/pub/release-66/fasta/'
#Hier word de lijst met beschikbare organisme binnengehaald via de functie curl.
# curl is te installeren via de terminal met het command sudo apt-get install curl
lijst=`curl $var | awk '{print $NF}'`
echo "de keuze 0 selecteert alles"
#hier wordt een directory aangemaakt om de files in weg te schrijven
mkdir -p dnaenpep
cd dnaenpep
#Hier wordt een keuze menu gecreeerd om het juiste organisme te kiezen.
select specie in $lijst
do
break
done
echo "Uw keuze is:" $specie
#Hier wordt de keuze "0" ingebouwd. Zodat alle genomen gedownload worden.
if [ "$specie" == "" ]
then
for i in $lijst
do
namen=$(curl $var$i/dna/ | awk '{print($NF)}')
for files in $namen; do curl $var$i/dna/$files -o $files
curl $var$i/pep/$files -o $files
done
done
fi
echo "de keuze 0 selecteert alles"
#Wanneer de loop niet uitgevoerd wordt, zal via nog een select statement de gekozen worden #welk DNA je van de ftp wil downloaden.
lijst2=`curl $var$specie/ | awk '{print $9}'`
echo $lijst2
select dnatype in $lijst2
do
break
done
echo "uw keuze is:" $dnatype
if [$dnatype == ""]
then
for i in $dnatype
do
wget -O DNAtype "$var$specie/dna/"
wget -O DNAtype "$var$specie/pep/"
done
fi
#Hier worden de files die in $dnatype gemaakt worden gedownload.
wget -O DNAtype "$var$specie/$dnatype/"
cat DNAtype | egrep "=" | tr '"' '\n' | sort | grep ^"ftp" |grep gz > Downlist.txt
wget -c -i Downlist.txt
exit

Your select statement should use an array and you can add additional items to the array or add them after the array name in the select statement.
lijst2=($(curl "$var$specie/" | awk '{print $9}')
lijst2+=("Another option" "Additional option" "Download all")
echo "${lijst2[#]}"
select dnatype in "${lijst2[#]}"
do
break
done
echo "uw keuze is: $dnatype"
or
lijst2=($(curl "$var$specie/" | awk '{print $9}')
echo "${lijst2[#]}"
select dnatype in "${lijst2[#]}" "Another option" "Additional option" "Download all"
do
break
done
echo "uw keuze is: $dnatype"
Which you choose depends on whether you want the added options in the array.
To download all, just iterate over the array (so you'll probably want to use the second version so you don't have to skip over "Download all", for example, since it's not a filename.
Additional notes:
Use $() instead of backticks for command substitution.
This statement if [$dnatype == ""] needs spaces: if [ $dnatype == "" ].
Quote all your variables when they are expanded. You have done this in some places, but not others.
Your long pipeline near the end can almost certainly be simplified. Without seeing example data I could only guess how.

Related

Why my code don't understand when I close the for loop?

I am writing a code in Shell Script trying to automatize some procedures in my data processing, but I facing some problems concerning the for. The code is the following. And it seems like he is understanding that I already closed the for loop.
#!/bin/bash
#modelos que serão usados
models=( 410_5x5_nocrust ) # 660_5x5_nocrust mtz_2x2_nocrust mtz_5x5_nocrust mtz_8x8_nocrust mtz_11x11_nocrust prem_nocrust prem s40rts_nocrust 660_5x5_s40rts_nocrust tx2015_nocrust)
#pasta base de onde todos os arquivos e programas estão
home_folder=/home/felipe/sda1_acess/RF_PROCESSING
for i in $models
do
#criando as pastas importantes para o trabalho
if ( ! -e $PWD/Listas )
then
mkdir $PWD/Listas
fi
if ( ! -e $PWD/Listas/"$i"_lists )
then
mkdir $PWD/Listas/"$i"_lists
fi
if ( ! -e $PWD/sacev )
then
mkdir $PWD/sacev
if
if ( ! -e $PWD/sacev/sacev_$i )
then
mkdir $PWD/sacev/sacev_$i/
fi
#setando a pasta onde os arquivos estão
folder=XH_preprocessed_"$i"_stations_1x1_RF_8s
#acessando a pasta
cd $home_folder/$folder
#numero de eventos q temos por modelo
v=(01 02) #03 04 05 06 07 08 09 10 11 12)
#Fazendo as listas
for j in $(v)
do
list=lista_"$i"_"$j".dat
xh_header "$i"_stations_1x1_RF_8s_01"$j"00X.cut.xh -h evnt stat arcs | sort -n -k25 > teste.dat
cat teste.dat | awk '{print $4" "$5" "$6" "$10" "$12" "$13" "$17" "$19" "$25}' | sort -n -k9 > $list
rm teste.dat
for k in $list
do
xh_2sac $PWD/$folder/"$i"_stations_1x1_RF_8s_01"$j"00X.cut.xh -s $k
touch log.dat
echo "r *$k*" > lixo1
echo "chnhdr KT0 'P'" >> lixo1
echo "chnhdr KT1 'Pdiff'" >> lixo1
echo "chnhdr KT2 'S'" >> lixo1
echo "chnhdr KT3 'Sdiff'" >> lixo1
echo "chnhdr KT4 'PcP'" >> lixo1
echo "chnhdr KT5 'PP'" >> lixo1
echo "chnhdr KT6 'SS'" >> lixo1
echo "chnhdr KT7 'P400s'" >> lixo1
echo "chnhdr KT8 'P670s'" >> lixo1
echo "w over" >> lixo1
echo "quit" >> lixo1
sac < lixo1
rm lixo1
done
done
cd $home_folder
mv $home_folder/$folder/lista* $home_folder/Listas/"$i"_lists/
mv $PWD/$folder/*.sac $PWD/sacev/sacev_$i/
#mv $PWD/$folder/log.dat $PWD/sacev/sacev_$i/
mv $PWD/sacev/sacev_$i/ $folder_path
done
the code's name is RFauto and when a do:
bash ./RF
I get the message:
RFauto.sh: row 79: syntax's error next to the unexpected token done' RFauto.sh: row 79: done'
(I had to translate the error massage from portuguese, but I hope it is understandable)
Like I said, he is kinda saying that I already closed the for loop, but when I remove it, it says that I need to close the for loop.
I will be vary grateful for any help!
you need for i in "${models[#]}" to iterate over the elements of the array.
This is correct shell syntax but not what you intend
if ( ! -e $PWD/Listas )
then
mkdir $PWD/Listas
fi
That will attempt to execute the command -e in a subshell and return the exit status negated.
I would expect to see the error "-e: command not found".
You want to use the [[...]] conditional construct
Additionally, mkdir -p will create a directory if it does not exist (including parent directories if they do not exist); if it does exist there is no error
cd $home_folder
mv $home_folder/$folder/lista* $home_folder/Listas/"$i"_lists/
mv $PWD/$folder/*.sac $PWD/sacev/sacev_$i/
#mv $PWD/$folder/log.dat $PWD/sacev/sacev_$i/
mv $PWD/sacev/sacev_$i/ $folder_path
The cd command changed $PWD. Are you sure that's what you want?
In general using $PWD in a program is risky: do you really know the user's location when they invoke the script?
i j k are not very descriptive variable names.
temporary files are usually not necessary.
#!/bin/bash
#modelos que serão usados
models=( 410_5x5_nocrust ) # 660_5x5_nocrust mtz_2x2_nocrust mtz_5x5_nocrust mtz_8x8_nocrust mtz_11x11_nocrust prem_nocrust prem s40rts_nocrust 660_5x5_s40rts_nocrust tx2015_nocrust)
#numero de eventos q temos por modelo
v=(01 02) #03 04 05 06 07 08 09 10 11 12)
#pasta base de onde todos os arquivos e programas estão
home_folder=/home/felipe/sda1_acess/RF_PROCESSING
for i in "${models[#]}"
do
#criando as pastas importantes para o trabalho
mkdir -p "$PWD/Listas/${i}_lists"
mkdir -p "$PWD/sacev/sacev_${i}/"
#setando a pasta onde os arquivos estão
folder="XH_preprocessed_${i}_stations_1x1_RF_8s"
#acessando a pasta
cd "$home_folder/$folder"
#Fazendo as listas
for j in "${v[#]}"
do
list="lista_${i}_${j}.dat"
xh_header "${i}_stations_1x1_RF_8s_01${j}00X.cut.xh" -h evnt stat arcs \
| sort -n -k25 \
| awk '{print $4, $5, $6, $10, $12, $13, $17, $19, $25}' \
| sort -n -k9 \
| while IFS= read -r k
do
xh_2sac "$PWD/$folder/${i}_stations_1x1_RF_8s_01${j}00X.cut.xh" -s "$k"
touch log.dat
sac << END_INPUT
r *$k*
chnhdr KT0 'P'
chnhdr KT1 'Pdiff'
chnhdr KT2 'S'
chnhdr KT3 'Sdiff'
chnhdr KT4 'PcP'
chnhdr KT5 'PP'
chnhdr KT6 'SS'
chnhdr KT7 'P400s'
chnhdr KT8 'P670s'
w over
quit
END_INPUT
done
done
cd "$home_folder"
mv "$home_folder/$folder/lista"* "$home_folder/Listas/${i}_lists/"
mv "$PWD/$folder/"*.sac "$PWD/sacev/sacev_${i}/"
#mv "$PWD/$folder/log.dat" "$PWD/sacev/sacev_${i}/"
mv "$PWD/sacev/sacev_${i}/" "$folder_path"
done

Getting error on running SH files downloaded by curl (As if there was a metadata preventing it from working)

I am trying to build a script/program that runs a sh file on internet without downloading it. All was working fine, with the exception that i am getting "This file/command doesnt exist" error on gedit, apt, etc. Then, I tried to modify the script to download the file and execute it after this instead of running bash <(curl -s --max-redirs 10 $2 -L), but still not working. I realized that if I finalize the script, CD to the downloaded SH file path and run it using "bash + foo.sh", it is still not working. The only method I found to run it is editing the SH file using gedit, copy all the content, remove the SH file, create a new SH file, paste and run it.
What is happening? Why is it not working? I want to run a SH script on the web just with bash without downloading it (bash and curl).
Here is my script (I will send it to my github when I end):
#!/bin/bash
input=$*
mkdir "$HOME/.br" > /dev/null 2>&1
mkdir "$HOME/.br/cache" > /dev/null 2>&1
rm "$HOME/.br/cache/*" > /dev/null 2>&1
if [ "$input" == "" ]
then
echo '[X] ERRO! | ERROR! | ¡ERROR!'
echo
echo '[PT]: Você precisa digitar um argumento. Digite "br -- help" para obter ajuda.'
echo
echo '[EN]: You need to type an argument. Type "br --help" to get help.'
echo
echo '[ES]: Debes ingresar un argumento. Escriba "br --help" para obtener ayuda.'
exit
fi
if [ "$input" == "--ajuda" ] || [ "$input" == "--help" ] || [ "$input" == "-h" ] || [ "$input" == "--ayuda" ] || [ "$input" == "-?" ]
then
echo '[?] AJUDA | HELP | AYUDA'
echo
echo '[PT]: Acesse este link para obter ajuda: '
echo
echo '[EN]: Go to this link for help: '
echo
echo '[ES]: Vaya a este link para obtener ayuda: '
exit
fi
if [ "$1" == "-u" ] || [ "$1" == "--url" ]
then
curl -s --max-redirs 10 $2 -L >$HOME/.br/cache/sh.sh
chmod +x "$HOME/.br/cache/sh.sh"
bash "$HOME/.br/cache/sh.sh" $1 $2 $3 $4 $5 $6 $7 $8 $9
else
curl -s --max-redirs 10 tiny.cc/brl_$1 -L >$HOME/.br/cache/sh.sh
chmod +x "$HOME/.br/cache/sh.sh" $1 $2 $3 $4 $5 $6 $7 $8 $9
fi
Also:
PS: I know that downloading files without reading the content before is unsafe, and because of it I pretend to make a dialog that shows its content, if the user wants it.
PS2: You can see that line: curl -s --max-redirs 10 tiny.cc/brl_$1 -L >$HOME/.br/cache/sh.sh. I am making a functionality that you can just short a link using tiny.cc with "brl_filename" and acess it typing "./script.sh filename" (That acess the SH file stored on 'tiny.cc/brl_filename'). It's like APT-GET, but its a SH script 'reader', and i'm using the tiny.cc as a 'database'. Imagine some website saying: "To install my app, just type foo filename or click in This button (foo://filename), and all twill be done. If you want to view what is inside the file, type foo -v filename or click in This button (foo://v:filename)!" - It's exactly it I'm trying to do, simplify the linux installing for all users, including the noobie users.
This project will be hosted on https://github.com/Felipecconde/br.

script bash Linux don't find error

I have to verify in a script bash that a folder exists. The problem is, it does but the script tells me that my file does not exist.
I don't find the error and I have searched on the internet and I do exactly the way it says to do( on Openclassroom, forum, ...).
here is my script:
#!/bin/bash
if [ $# -ne 1 ] && [ -d $1 ]; then
echo "Usage : $0 dir">/dev/stderr
exit 1
fi
backup="~/backup"
echo $backup , argument = $1
if [ ! -e ${backup} ]; then
echo "Le dossier backup n'existe pas">/dev/stderr
exit 1
fi
if [ ! -d $backup ]; then
echo "le document backup n'est pas un fichier">/dev/stderr
exit 1
fi
if [ -w $backup ]; then
echo "Le dossier backup n'est pas protégé en écriture">/dev/stderr
exit 1
fi
il qu$if [! chmod u=+w $backup ]; then
echo "une erreur c'est produite">/dev/stderr
exit 1
fi
And what it said in the shell + the proof that the file backup exist in the correct repertory:
guy#PC-DE-GUY:~/bash/Chap9$ ./backup.sh ~/seance06/
~/backup , argument = /home/guy/seance06/
Le dossier backup n'existe pas
guy#PC-DE-GUY:~/bash/Chap9$ ~/backup
bash: /home/guy/backup : est un dossier
guy#PC-DE-GUY:~/bash/Chap9$ cd ~/backup
guy#PC-DE-GUY:~/backup$
The issue is with the ~ character inside quotes, in backup="~/backup" (line 6). BASH processes it as a character, not as an alias to your home directory, so your code runs the checks on the string '~/backup', instead of '/home/guy/backup'.
To use ~ as an alias to your home directory, it should be outside quotes: backup=~/backup
If you want to hardcode your home directory, I suggest you use $HOME instead of ~. It's clearer to understand.
You can test what I tried to explain with the following code:
#!/bin/bash
# Save this file as test.sh
# run this script with ~ as an argument:
# ./test.sh ~
echo "Value for \$HOME: $HOME"
echo "Value for ~ inside quotes: ~"
echo "Value for ~ outside quotes:" ~
echo "Value for \$1: $1"
If you save the code above as test.sh and you run it as: ./test.sh ~, outputs will be:
Value for $HOME: /home/guy
Value for ~ inside quotes: ~
Value for ~ outside quotes: /home/guy
Value for $1: /home/guy

Create folders at same time in bash

I need to create a number of folders with the same name but with a number at the end.
User should write a number and the script should create these numbers of folders. I don't know how to link the number and the number os folders.
Here is my script
#!/bin/bash
echo "(1617S2)" A.C.B.S
pwd
date
NOM="A.C.B.S"
echo $NOM
echo -n "Introduce el numero de carpetas que quieras :"
read x
if (($x<=10)); then
echo "Son $x carpetas"
else (($ <10))
echo -n "El número de carpetas tiene que ser entre 1 i 10 :"
read x2
echo "Son $x2 carpetas"
fi
cd ..
cd /var
sudo mkdir carpetaprincipal
cd ..
cd /var/carpetaprincipal
sudo mkdir carpeta {1..10}
You could use seq with xargs to iterate and create the number of folders chosen for the input:
#!/bin/bash
echo "(1617S2)" A.C.B.S
pwd ; date
NOM="A.C.B.S" ; echo $NOM
function makeFolders () {
echo -n "Introduce el numero de carpetas que quieras :"
read -r x
if [[ "$x" -lt 11 ]] && [[ "$x" -gt 0 ]]; then
echo "Son $x carpetas"
cd ../var || exit
mkdir carpetaprincipal
cd carpetaprincipal || exit
seq "$x" | xargs -I{} mkdir carpeta_{}
fi
if [[ "$x" -lt 1 ]] || [[ "$x" -gt 10 ]]; then
echo "El número de carpetas tiene que ser entre 1 i 10!"
makeFolders # you could optionally exit 1 here
fi
}
makeFolders
There were some other issues with your script, mainly the logic didn't make sense. If you put in more than 10 or less than 1 then the script still allowed the user to create folders which are above are below what is supposed to be allowed. Putting those methods within in a function also allows you to return to the input line if there is an error. Also, read should include -r, otherwise it has the potential to mangle backslashes.
To do multiple mkdir while looping a variable number of times:
x2=4
i=1
while [ "$i" -le "$x2" ]
do
sudo mkdir carpeta$1
i=$(($i + 1))
done

BASH Linux : syntax error « ;; »

i have a syntax error « ;; »
Syntax error near unexpected token « ;; »
my code
#!/bin/bash
# Bash Menu
clear
echo "Decryptor"
PS3='entrez votre chois: '
options=("update" "decryptor" "Quit")
select opt in "${options[#]}"
do
case $opt in
"update")
php updatekey.php
break
;;
"decryptor")
#Nom de la video
read -p "Nom de la série : " name
#detection du fichier .png
find . -name "*.png" | while read line
oname="$(basename "${line}" .png)"
#décryption du fichier png
php -e AES.class.php "${oname}".png
#on change le nom du fichier
mv "${oname}".ass "${name}".ass
read -p "voulez vous télécharger la video (Y/N)? "
[ "$(echo $REPLY | tr [:upper:] [:lower:])" == "y" ] || exit
read -p "entrez liens :" src
read -p "liens vod" vod
rtmpdump -v -T '567ghgh' -r "$vod" -a "vod" -f "WIN 13,0,0,182" -W "http://yoyo.com/components/yoyo.swf" -p "http://yoyo.com" -y "mp4:$src" -o "$name.mp4"
break
;;
"Quit")
break
;;
*) echo invalid option;;
esac
done
is part of code with error
why I get an error I modified the script a bit and this part to not move and I now have an error
What can be the cause
thank you :)
Line 21 contains the beginning of an incomplete while statement. The parser only notices because ;; is illegal when it's still looking for the do.
find stuff | while read line
echo you can have multiple commands here --
echo the exit code of the expression is
echo examined by '"while"'
do
echo ... Body of while loop
done
Your code lacks the do and done parts, and it's unclear to Bash (and to us) where they should go.

Resources