[Risolto] [bash] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
rei1983
Prode Principiante
Messaggi: 3
Iscrizione: venerdì 6 maggio 2022, 10:01
Desktop: Ubuntu
Distribuzione: Ubuntu 22.04 LTS
Sesso: Maschile

[Risolto] [bash] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da rei1983 »

Salve a tutti ragazzi,

Innanzitutto, ringrazio in anticipo chiunque vorrà e potrà darmi una mano a capire dove sbaglio. Sto, per la prima volta, tentando di seguire la guida per Linux from scratch e credevo andasse tutto nel migliore dei modi ma, al momento di scaricare tutti i packages necessari (procedura che ho tentato di automatizzare ricorrendo alla creazione di un file .csv dal nome, appunto, packages.csv), sto riscontrando un problema con sed che mi impedisce il download. Sono quasi convinto di aver capito dove sia l'errore ma non so davvero come correggerlo.
Questo è il mio script per il download dei diversi packages (il nome di questo file è: download.sh):

Codice: Seleziona tutto

cat packages.csv | while read line; do
  NAME="`echo $line | cut -d\; -f1`"
  VERSION="`echo $line | cut -d\; -f2`"
  URL="`echo $line | cut -d\; -f3 | sed "s^@^$VERSION^g"`"
  MD5SUM="`echo $line | cut -d\; -f4`"
  CACHEFILE="$(basename "$URL")"

  if [ ! -f "$CACHEFILE" ]; then
      echo "Sto scaricando $URL"
      wget "$URL"
      if ! echo "$MD5SUM $CACHEFILE" | md5sum -c >/dev/null; then
        rm -f "$CACHEFILE"
        echo "Verifica di $CACHEFILE fallita! il codice MD5 non combacia!"
        exit 1
      fi
  fi
done
Nell'espressione regolare che ho creato con sed, il simbolo ^, l'ho semplicemente usato come separatore, perchè, l'uso dello / mi dava un ulteriore errore.

Nel mio file packages.csv, per ogni URL, ho rimpiazzato il numero di versione con una @ (il mio fine è quello di riuscire a scaricare il relativo pacchetto, fintantoché esso mantenga l'attuale nomenclatura) e credo proprio che sia questo ciò che mi fa saltare tutto. Sbaglio qualcosa e all'esecuzione dello script e la @ non viene rimpiazzata con il corrispondente numero di versione.

Questo poi è lo script che dovrebbe consentirmi di scaricare effettivamente i packages (e credo che qui non ci siano errori... correggetemi se sbaglio :D ):

Codice: Seleziona tutto

cp -rf *.sh packages.csv "$LFS/sources"
cd "$LFS/sources"
export PATH="$LFS/tools/bin:$PATH"



source download.sh
Se, infine, dovvesse essercene bisogno, potrei postare qui anche il file packages.csv che adesso non metto perchè non so se è possibile farlo.

Ringrazio nuovamente chiunque mi darà una mano.
Saluti
Ultima modifica di rei1983 il venerdì 6 maggio 2022, 18:19, modificato 4 volte in totale.
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [Linux from scratch] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da vaeVictis »

Non serve il file intero, copia incolla qualche linea per dare un'idea della struttura di questo file csv. Ne basta anche una.

Ció detto, il tuo codice presenta margine per essere migliorato.
1) puoi leggere il file senza usare cat (cerca in rete, poi magari chiedi)
2) non serve usare echo e poi cut, bash mette a disposizione le operazioni su stringa
3) la riga:

Codice: Seleziona tutto

NAME="`echo $line | cut -d\; -f1`"
contiene due errori. La command substitution con il backtick é deprecata. Usa la versione

Codice: Seleziona tutto

foo=$(comando)
come vedi, non ho usato le doppie virgole dopo l'uguale. In questo caso non servono, perché nellássegnamento di una variabile Bash giá crea di suo un "double quotes context" per il secondo membro.
(tradotto, ce le mette Bash le virgolette)
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
rei1983
Prode Principiante
Messaggi: 3
Iscrizione: venerdì 6 maggio 2022, 10:01
Desktop: Ubuntu
Distribuzione: Ubuntu 22.04 LTS
Sesso: Maschile

Re: [Linux from scratch] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da rei1983 »

@vaeVictis Innanzitutto ciao e grazie per la rapida risposta. Provvedo subito a migliorare il mio codice e ti icollo qualche riga del mio packages.csv così che tu possa dargli un'occhiata.

Codice: Seleziona tutto

acl,2.3.1,https://download.savannah.gnu.org/releases/acl/acl-@.tar.xz,95ce715fe09acca7c12d3306d0f076b2
attr,2.5.1,https://download.savannah.gnu.org/releases/attr/attr-@.tar.gz,ac1c5a7a084f0f83b8cace34211f64d8
autoconf,2.71,https://ftp.gnu.org/gnu/autoconf/autoconf-@.tar.xz,12cfa1687ffa2606337efe1a64416106
Se noti, come avrai visto anche dallo script, nella prima colonna ho messo il nome, nella seconda la versione, nella terza l'URL per il download e nella quarta, il codice MD5 (P.S. già il primo mi da errore).

Grazie ancora per l'aiuto che mi stai dando e per quello che mi darai
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [Linux from scratch] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da vaeVictis »

La prima modifica che farei é questa:

Codice: Seleziona tutto

old_ifs=$IFS
IFS=','
while read -a attributes line; do
# NAME é attributes[0], VERSION é attributes[1], URL é attributes[2], MD5SUM é attributes[3]
    attributes[2]=$(echo ${attributes[2]} | sed "s|@|${attributes[1]}|")
    CACHEFILE="${URL##*/}"
    IFS=$old_IFS
    
    if [ ! -f "$CACHEFILE" ]; then
	##
	## fai quell che devi fare
	##
    fi
    IFS=','
done < packages.csv
Invece di fare tutto quel bordello con cut, cambia la variabile IFS e poi leggiti riga per riga (nota che ho cambiato la sintassi, rimuovendo cat e usando l'idioma corretto per il ciclo while).
Cambiando la variabile IFS in virgola ( , ), la linea ti viene automaticamente splittata dal comando read e ogni parte viene inserita in un array (che ho chiamato attributes).
In questo modo avrai le corrispondenze:

Codice: Seleziona tutto

NAME é attributes[0], VERSION é attributes[1], URL é attributes[2], MD5SUM é attributes[3]
Quindi, modifichi attributes[2], il cui contenuto corrisponde a quello della precedente variabile URL, analogamente a come facevi prima:

Codice: Seleziona tutto

attributes[2]=$(echo ${attributes[2]} | sed "s|@|${attributes[1]}|"
Per quanto riguarda CACHEFILE, invece di usare basename che é una chiamata a una funzione esterna a bash, puoi usare tranquillamente le operazioni sulle stringhe per ottnere la stessa cosa. Il motivo é lo stesso per cui non é il caso di usare cut se non necessario: una chiamata a cut/basename ha un overhead che non hai se usi direttamente read o la manipolazione delle stringhe, che sono builtin di bash.
Subito dopo reimposti la variabile IFS per evitare che eventuali virgole ti vengano stampate come fossero degli spazi.
Quindi fai quello che devi fare.
Poi reimposti la variabile IFS al valore virgola e ricominci da capo.

Nota: ho eliminato il codice all'interno del ciclo if, perché poi magari se ne parla, prima vediamo se questo é chiaro.

Un esempio per questo codice é il seguente:

Codice: Seleziona tutto

line="acl,2.3.1,https://download.savannah.gnu.org/releases/acl/acl-@.tar.xz,95ce715fe09acca7c12d3306d0f076b2"

old_IFS=$IFS
IFS=','

read -a attributes<<<"$line"
# echo ${line##,}
# exit
echo "NAME"
echo "${attributes[0]}"
echo "*********"
echo "VERSION"
echo ${attributes[1]}
echo "*********"
echo "URL con la @"
echo ${attributes[2]}
echo "URL con la @ correttamente sostituita"
echo ${attributes[2]} | sed "s|@|${attributes[1]}|"
echo "*********"
echo "MD5SUM"
echo ${attributes[3]}
echo "*** *** ***"
echo "linea con gli spazi al posto della virgola"
echo ${line}
echo "*********"
echo "linea con le virgole correttamente visualizzate"
IFS=$old_IFS
echo ${line}
il cui output é:

Codice: Seleziona tutto

NAME
acl
*********
VERSION
2.3.1
*********
URL con la @
https://download.savannah.gnu.org/releases/acl/acl-@.tar.xz
URL con la @ correttamente sostituita
https://download.savannah.gnu.org/releases/acl/acl-2.3.1.tar.xz
*********
MD5SUM
95ce715fe09acca7c12d3306d0f076b2
*** *** ***
linea con gli spazi al posto della virgola
acl 2.3.1 https://download.savannah.gnu.org/releases/acl/acl-@.tar.xz 95ce715fe09acca7c12d3306d0f076b2
*********
linea con le virgole correttamente visualizzate
acl,2.3.1,https://download.savannah.gnu.org/releases/acl/acl-@.tar.xz,95ce715fe09acca7c12d3306d0f076b2
p.s.: comunque fai attenzione perché nel comando cut hai usato il punto e virgola come delimitatore dei campi, invece della virgola. é il motivo dell'errore. Un'altra cosa che é inutile é il comando g di sed. Tu fai una sola sostituzione, non ti interessa l'opzione g.
Ultima modifica di vaeVictis il venerdì 6 maggio 2022, 18:49, modificato 1 volta in totale.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
rei1983
Prode Principiante
Messaggi: 3
Iscrizione: venerdì 6 maggio 2022, 10:01
Desktop: Ubuntu
Distribuzione: Ubuntu 22.04 LTS
Sesso: Maschile

Re: [Linux from scratch] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da rei1983 »

@vaeVictis grazie davvro. Problema risolto e modifiche apportate come da te suggerito; non so davvero come ringraziarti :D
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [Linux from scratch] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da vaeVictis »

rei1983 ha scritto:
venerdì 6 maggio 2022, 18:02
non so davvero come ringraziarti :D
Allora ti suggerisco io il modo: cambia il tag nel titolo del primo messaggio della discussione da [Linux from scratch] a [bash] e metti [Risolto] all'inizio. :)

Comunque, non so che package manager stai usando e non so se sia disponibile quando installi le altre cose, ma in generale i package manager hanno una opzione per installare i pacchetti che sono elencati su un file di configurazione, come spiegano per esempio in questa discussione per apr-get
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [Risolto] [bash] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da crap0101 »

e volendo

Codice: Seleziona tutto

crap0101@orange:~/test$ diff  /tmp/foo.sh /tmp/foo2.sh 
18c18
< echo ${attributes[2]} | sed "s|@|${attributes[1]}|"
---
> echo ${attributes[2]/@/${attributes[1]}}
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [Risolto] [bash] Problema con sed per un'espressione regolare che immetta la versione del package da scaricare

Messaggio da vaeVictis »

Giusto, così non chiami un comando esterno neanche per la sostituzione. Tutta quella pippa per non usare cut, poi ho usato sed :D
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 12 ospiti