Newsgroup: it.comp.os.linux.iniziare
Titolo: bash: passaggio di parametri

Ho visto che con  la bash si possono fare script abbastanza evoluti, ho 
guardato diversi esempi sulle funzioni ma non ho ancora capito se esiste 
il passaggio di parametri per variabile: esiste?
-- 
Sandro kensan 
www.kensan.it
 & 
www.qiqi.it
 geek site

 esiste?
 
Non saprei: se però fai un esempio di quel che intendi...
-- 
Bye, Lem
Ceterum censeo ISLAM esse delendum
_________________________________________________________________
Non sprecare i cicli idle della tua CPU, né quelli della tua GPU.
 
http://www.worldcommunitygrid.org/index.jsp
 
http://www.rnaworld.de/rnaworld/
 
http://home.edges-grid.eu/home/
 
 
http://www.gpugrid.net/
 

 il passaggio di parametri per variabile: esiste?
 
Si,
 
bye,
 
-- 
 
piergiorgio

 il passaggio di parametri per variabile: esiste?
 
Io conosco il passaggio  dei parametri per valore, per riferimento e
per nome, sono i più comuni, ci sono alte modalità più esoteriche,
ma il passaggio dei parametri per variabile è una cosa troppo nuova
per me. Ha solo poche ore di vita.


Facebook: Massimo Bacilieri

 ...
 
 
Questo è un esempio del passaggio di parametri 
ad una funzione non del passaggio di parametri 
per variabili che è un concetto che non esiste;
forse tu passi ad una funzione una variabile per 
variabili? Non farmi ridere.


Non correlato con il post originale, ma forse utile:
 
#!/bin/bash
A='B'
B='hello'
echo ${!A}
 
Ha un interessante output,
 
bye,
 
-- 
 
piergiorgio

 Non saprei: se però fai un esempio di quel che intendi...
 
Penso di avere sbagliato il termine esatto, quello preciso è per 
riferimento:
 
https://it.wikipedia.org/wiki/Funzione_%28informatica%29#Passaggio_per_indirizzo_o_per_riferimento
 
 
in pratica si passa la variabile la quale viene gestita dalla funzione e 
all'uscita della funzione la variabile si modifica di conseguenza. 
Qualcosa di questo tipo:
 
Function f(var $a,$b) {
$a=$b+1;
$b=0;
}
 
$c=7;
$d=8;
f($c,$d);
echo $c $d;
 
l'echo restituisce 9 0



Grazie :)


 per me. Ha solo poche ore di vita.
 
 
Si, esatto per riferimento. All'epoca del pascal questo passaggio di 
parametri veniva indicato con un var prima della variabile. In effetti 
si passa la "variabile" e non il suo contenuto o valore, è corretto il 
termine riferimento ovvero in assembler l'indirizzo della cella di memoria.



 
Grazie per l'esempio ma non si passa la "varibile" ma il suo valore. 
Comunque il termine corretto che volevo indicare è "riferimento" e non 
variabile.
 
Nell'esempio pippero dovrebbe essere una variabile, ho fatto un po' di 
tentativi e questo pare funzionate:
 
#!/bin/bash
PARAM="cazzabubbola"
 
function f () {
     echo $PARAM $@
((a=23))
}
 
((a=1))
f a
echo $a
 
il primo echo restituisce il nome della variabile mentre il secondo echo 
restituisce il valore 23. Però dovrebbe anche essere possibile avere 
nomi diversi delle variabili nell'interno e all'esterno della funzione.



Dato che non c'e` isolamento, mi pare, tra la funzione
ed il "main", qualunque variabile non passata come
parametro e` usata per riferimento invece che per valore.
 
Questo ad occhio, non ho provato,
 
bye,
 
-- 
 
piergiorgio

 il passaggio di parametri per variabile: esiste?
 
Poi ho cercato meglio su questo passaggio di parametri per variabile in 
quanto era esattamente quello che ricordavo. Ho trovato che questo modo 
di chiamare il passaggio di parametri per riferimento è tipico del 
pascal che credo pochi conoscano, comunque esiste basta cercare con 
google la frase esatta:
 
"passaggio di parametri per variabile"
 
Per esempio qui si dice:
http://www.grid.unina.it/Didattica/FI/EI-Cristaldi/didattica/manuale/page7a.htm
 
 
Esso corrisponde a quello che in Pascal si chiama "passaggio di 
parametri per variabile" e consente la realizzazione di funzioni con 
effetti laterali sui parametri attuali:
 
   void Change(int* IntPtr) {
 
     *IntPtr = 5;



Non ho capito bene ma se parli dell'isolamento tra il main e la funzione 
questo c'è in quanto $a e $b sono ovviamente locali e non esistono fuori 
dallo "scope" della funzione.
 
In altre parole $a e $b sono variabili che vengono allocate appena la 
funzione viene chiamata e deallocate all'uscita dalla funzione.
 
Poi quando parli di qualsiasi variabile non passata come parametro penso 
tu non intenda i parametri formali $c e $d e i parametri attuali $a e $b.
 
Io credo che l'esempio qui sopra con il suo output di 9 e 0 abbia una 
sola spiegazione.


 Ha un interessante output,
 
Si tratta della sostituzione indiretta. 
Con questa si può simulare il passaggio di parametri per riferimento.
Quale è la novità?

 Quale è la novità?
 
Nessuna, probabilmente, ma magari la cosa
puo` interessare qualcuno che ancora non
conosce questa possibilita`.
 
bye,
 
-- 
 
piergiorgio

 sola spiegazione.
 
Non saprei, quel codice non credo funzioni in bash.
 
bye,
 
-- 
 
piergiorgio

On 2013-05-30 00:37, Sandro kensan wrote:
[...]
 
Ad esempio (trovato con una semplice ricerca):
 
pathmunge () {
        if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
           if [ "$2" = "after" ] ; then
              PATH=$PATH:$1
           else
              PATH=$1:$PATH
           fi
        fi
}
 
La variabile $PATH e` modificata all'interno
della funzione e risulta valida dopo la chiamata.
 
Di fatto e` passata per "reference" e non per "value".
In realta`, non e` passata affatto, esiste e basta.
 
bye,
 
-- 
 
piergiorgio


Ovviamente no. Sinceramente avevo dato per scontato che avesse espresso 
in un modo contorto il semplice passaggio delle variabili... ma così non 
era... Amen.


 }
 
Ah! Ma i puntatori, insomma! E chiamali col loro nome! :-)
Temo che in bash non esistano, però.


 Il che non e` elegante, ma e` usabile.
 
In pascal e in molti altri linguaggi tra cui il c il fatto di non 
modificare le variabili globali (o comunque quelle dello scope del 
programma (o funzione) che ha chiamato la funzione) ha una rilevante 
importanza in quanto posso scrivere una funzione che mi calcola la somma 
di due frazioni e usarla in diversi programmi con un semplice include 
(php) o source (bash), senza dannarmi l'anima per il fatto che le 
variabili interne alla funzione hanno un nome o un altro.
 
Ovviamente se uso variabili globali devo sempre stare li a modificare il 
nome delle variabili quando includo una funzione in quanto quest'ultima 
vuole dei nomi prefissati. Se uso più volte la funzione creo sicuramente 
una grande confusione con continui rinominazioni delle variabili.


 nomi diversi delle variabili nell'interno e all'esterno della funzione.
 
Sembra funzionare perché in questo modo tu dentro la funzione riassegni 
il valore alla variabile globale "a". Ma non è che passi il riferimento 
(puntatore) alla variabile come parametro.
 
Tieni presente che in bash non esistono le variabili "locali", in 
sostanza sono tutte "globali". Se assegni una variabile in una funzione, 
questa variabile la potrai leggere anche "fuori".
 
Però puoi anche usare una funzione per valorizzare direttamente una 
variabile:
 
#!/bin/bash
function assegna () {
	echo "output"
}
A=`assegna`
echo $A
 
e vedrai che $A vale "output".
Puoi anche combinare l'input, ovvero fare qualcosa di questo tipo:
 
function assegna () {
	echo "inserito: $1"
}
A=`valore`
echo $A
 
e il risultato sarà "inserito: valore".


 e il risultato sarà "inserito: valore".
 
Errata corrige:
 
ovviamente deve essere:
A=`assegna valore`



 
Scusa :)
 
sono legato a una vecchia terminologia che forse è stata abbandonata ma 
che ai tempi del pascal era molto usata. A parte i puntatori che non 
esistono in molti linguaggi mi riferisco al passaggio di parametri per 
riferimento.
 
Per esempio in php si scrive:
 
<?php
function aggiungi_qualcosa(&$string)
{
     $string .= 'e qualche altra cosa.';
}
$str = 'Questa è una stringa, ';
aggiungi_qualcosa($str);
echo $str;    // l'output sarà 'Questa è una stringa, e qualche altra cosa.'
?>
 
In pascal si usa:
 
Ecco un esempio di passaggio per riferimento usando la keyword var:
 
procedure DoubleTheValue (var Value: Integer);
begin
   Value := Value * 2;
end;
 
In questo caso, il parametro e' usato sia per passare un valore alla 
procedura sia per ritornare un nuovo valore al codice chiamante. Quando 
si scrive:
 
var
   X: Integer;
begin
   X := 10;
   DoubleTheValue (X);
 
il valore della variabile X diventa 20, siccome la funzione usa un 
riferimento alla locazione di memoria originale della variabile X, 
cambiando il suo valore iniziale.
 
Per il C si usano i puntatori:
 
   void Change(int* IntPtr) {
 
     *IntPtr = 5;
 
   }
 
Per il C++ non lo so.


 ...
 
A parte la bruttezza del sito (è poco leggibile, è un docente universitario
cazzo) parla di "parametri attuali" invece che "parametri effettivi" e
di "effetti laterali" invece di "effetti collaterali" o "azione a distanza".
La proprietà di linguaggio distingua i professionisti dai dilettanti e dai
praticoni.
 
\flame off
 
Comunque il sito è interessante perché mostra come si può simulare
il passaggio di variabili per  riferimento con  i puntatori, così come
già hanno fatto vedere come si può simulare la stessa cosa con l'
espansione indiretta dei parametri nella  bash.
 
Però fa attenzione, la bash ha molte particolarità e stranezze.
Prima di tutto il concetto stesso di variabile come contenitore non è
il modello adottato dalla bash. in secondo luogo già ti hanno fatto 
notare che le regole di visibilità non esistono per cui tutte le variabili
sono globali. Infine esiste un solo tipo di variabile, la stringa.
 
In effetti le variabili sono sottoposte ad una espansione ed i parametri  
si determinano dopo la /word/ /splitting/ o separazione in parole per cui
i parametri non vengono passati nè per nome nè per valore, ma puttosto
per espansione delle macro, che è uno dei modi esoterici a cui accennavo
prima. 
 
Buonanotte
 
 

 variabili interne alla funzione hanno un nome o un altro.
 
Puoi ottenere lo stesso scopo usando i parametri posizionali.
 
#!/bin/bash
 
function calcola () {
	V1=$1
	V2=$2
	R=$((V1 + V2))
	echo $R
}
 
RIS=`calcola 5 7`
echo $RIS
 
e otterrai "12"
La function calcola() la puoi mettere in un file a parte, da richiamare 
in tutti gli script in cui ti serve con "source". Non devi preoccuparti 
del nome delle variabili, basta passare i parametri (qui ho messo dei 
numeri, ma potrebbero essere a loro volta delle variabili, es. calcola 
$VAL1 $VAL2), e la funzione andrà bene sempre.


 era... Amen.
 
No problem. Però avevo dimenticato che ai tempi del Pascal si 
usava dire, in modo molto scorretto, "parametro variabile". 
 

 conosce questa possibilita`.
 
Nessun problema, anzi ha fatto una cosa buona e giusta.
Il problema era solo capire cosa voleva dire l'OP.

 una grande confusione con continui rinominazioni delle variabili.
 
Basta fare due copie, una prima ed una dopo
la chiamata a funzione.
 
Cioe`:
 
variabile_della_funzione=variabile_xyz
f()
variabile_xyz=variabile_della_funzione
 
Dove "variabile_della_funzione" e` usata nella
funzione, ovviamente, all'interno.
 
Certo, non e` il massimo, ma funziona,
 
D'altro canto, non mi pare le funzioni bash
abbiano la possibilita` di ritornare valori...
 
bye,
 
-- 
 
piergiorgio

 In pascal si usa:
 
http://www.ee.ryerson.ca/~elf/hack/realmen.html
 
 
bye,
 
 
-- 
 
piergiorgio

 l'echo restituisce 9 0
 
Se capisco bene, stai cercando la soluzione ad un problema
di questo tipo: tu vuoi passare alla funzione alcuni valori
indicati da variabili (cioè da parametri) di volta in volta
*diverse* (cioè con diversi *nomi*). Vuoi che la funzione
modifichi questi valori, e li riassegni proprio alle variabili
con quei rispettivi *nomi*. È così? 
 
Per esempio:
 
lem@biggy:/tmp$ pippo=1; pluto=13; paperino=144
lem@biggy:/tmp$ f() { export -n "$1"=$(($1+50)); export -n "$2"=$(($2+500)); }
 
Usi export, e non declare, perché declare, chiamato dentro a una
funzione, genererebbe variabili locali alla funzione
 
Questa funzione aumenta di 50 il valore della prima variabile
passata per riferimento (qui il riferimento è il nome della
variabile), di 500 il valore della seconda variabile passata
per riferimento.
 
lem@biggy:/tmp$ f pippo paperino
 
Nota che qui chiamo la funzione dandole in pasto i meri
*nomi* delle variabili (i riferimenti): ci pensa poi la funzione
a richiamare i valori attribuiti alle variabili aventi quei nomi:
nella qual cosa non ci sono problemi, siccome le funzioni vengono
eseguite nella medesima shell in cui sono chiamate (e non in
subshell).
 
lem@biggy:/tmp$ echo "$pippo $pluto $paperino"
51 13 644
lem@biggy:/tmp$ f pippo pluto
lem@biggy:/tmp$ echo "$pippo $pluto $paperino"
101 513 644
lem@biggy:/tmp$ f pluto paperino
lem@biggy:/tmp$ echo "$pippo $pluto $paperino"
101 563 1144
-- 
Bye, Lem
Ceterum censeo ISLAM esse delendum
_________________________________________________________________
Non sprecare i cicli idle della tua CPU, né quelli della tua GPU.
 
http://www.worldcommunitygrid.org/index.jsp
 
http://www.rnaworld.de/rnaworld/
 
http://home.edges-grid.eu/home/
 
 
http://www.gpugrid.net/
 

 abbiano la possibilita` di ritornare valori...
 
Certamente, così si deve fare. Comunque il mio post iniziale aveva la 
domanda se in bash si arrivasse a passare le variabili per riferimento 
in una funzione e mi pare che la risposta sia negativa e che il 
workaround sia quello che hai mostrato tu qui sopra.
 
Mi dispiace poi di avere usato una terminologia legata al pascal che è 
superata e che ha allungato il 3ad molto più del dovuto.


 lem@biggy:/tmp$ f() { export -n "$1"=$(($1+50)); export -n "$2"=$(($2+500)); }
 
Esatto questa mi pare la soluzione penso che funzioni come negli altri 
linguaggi di programmazione come nel c o nel pascal o nel php.


 bye,
 
:)
 
Real programmers don't need abstract concepts to get their jobs done: 
they are perfectly happy with a keypunch, a FORTRAN IV compiler, and a beer.
 
     Real Programmers do List Processing in FORTRAN.
     Real Programmers do String Manipulation in FORTRAN.
     Real Programmers do Accounting (if they do it at all) in FORTRAN.
     Real Programmers do Artificial Intelligence programs in FORTRAN.
 
If you can't do it in FORTRAN, do it in assembly language. If you can't 
do it in assembly language, it isn't worth doing.
 
Comunque siamo OT.
 
In assembly 6502 un passaggio per riferimento è qualche cosa del tipo:
 
LDA [$FFF0]
INCA
STA [$FFF0]
 
o ancora meglio lavorare sullo stack con una indirezione rispetto allo 
stack pointer (S) con un offset negativo per individuare la propria 
variabile all'interno dello stack. Il passaggio di parametri per 
riferimento si può fare pure in assembly.


 prima.
 
Grazie, informazioni molto utili. Quoto solo questo ma l'idea generale 
del linguaggio bash non lo conosco per cui mi serve avere queste idee 
generali sul linguaggio per orientarmi.
