[bash] Expandera subkommando vid tilldelning av variabel

Permalänk
Medlem

[bash] Expandera subkommando vid tilldelning av variabel

Under tiden jag håller på att googla efter lösning, så gör jag ett försök här också.

Mitt problem är följande:
Jag har en fil som sourcas under uppstart där följande innehåll finns:

if [ -f '/etc/timezone' ]; then export TZ="$(cat /etc/timezone)" fi

Detta fungerar som förväntat, men när jag försöker hämta variabeln från C# (mono) genom följande:

Environment.GetEnvironmentVariable("TZ")

Så får jag ut detta som resultat:

"$(cat /etc/timezone)"

Jag är (nästan) säker på att detta fungerat innan bash patchades för shellchock. D.v.s. att mono klarar läsa ut värdet från subkommandot och inte kommandot i sig självt. Alternativt att beteendet ändrats mellan mono 3.8.0 och 3.10.0. Oavsett är det irrelevant för min fråga.

Till min fråga: kan jag, då jag exporterar $TZ, säga till bash att inte lagra subkommandot utan expandera variablen och lagra resultatet som en sträng istället? Värdet måste läsas ut från /etc/timezone då det används på flera håll i systemet.

En nödlösning (som jag helst vill undvika) är något i stil med detta:

$ echo "export TZ=$(cat /etc/timezone)" > /tmp/foo $ source /tmp/foo

Visa signatur

..:: RiJo ::..
Computer: Lenovo X300
Platform: Gentoo

Permalänk
Hedersmedlem

Skalet ska mig veterligen genomföra processubstitutionen vid anropet så som det är skrivet. En notis är att POSIX säger att du inte behöver citationstecken runt $(cat /etc/timezone) i variabeltilldelningen, men de ska ej heller inverka på något sätt. Hade de däremot varit "enkla fnuttar" så hade det gjort att substitutionen inte utförts, vilket hade fått det resultat du märker.

Kontrollera först och främst om $TZ är satt till vad du tror det är i det skal från vilket du startar C#, dvs ett enkelt `echo $TZ` eller `printenv TZ` (notera att dessa inte är ekvivalenta; `printenv` skriver bara exporterade variabler). Om inte detta stämmer så har du missat något steg; möjligen har du ändrat konfigurationsfiler utan att ha läst in dem korrekt.

I vilket fall så är det inte ett snyggt sätt att tilldela en fils innehåll till en variabel (se UUOC ). Ett mer "skalvänligt" sätt utan extra processer vore:

TZFILE="/etc/timezone" if [ -f "$TZFILE" ]; then read TZ < "$TZFILE" export TZ fi

(Vill man vara än mer tydlig så skulle man kunna testa även `-r` för att säkerställa att filen även är läsbar.)

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Tack för svaret phz. I bash kan jag läsa ut värdet korrekt, men jag misstänker som sagt att det är bara för att bash tolkar subkommandot korrekt.

Jag har tillsvidare löst problemet genom följande (köra det genom eval):

if [ -f '/etc/timezone' ]; then eval export TZ="$(cat /etc/timezone)" fi

Om något har bättre förslag så är de välkomna!

Edit: lösningen phz gav löser nog mitt problem på snyggaste sätt. Tack igen för hjälpen!

Visa signatur

..:: RiJo ::..
Computer: Lenovo X300
Platform: Gentoo

Permalänk
Hedersmedlem
Skrivet av RiJo:

Tack för svaret phz. I bash kan jag läsa ut värdet korrekt, men jag misstänker som sagt att det är bara för att bash tolkar subkommandot korrekt.

Jag har tillsvidare löst problemet genom följande (köra det genom eval):

if [ -f '/etc/timezone' ]; then eval export TZ="$(cat /etc/timezone)" fi

Om något har bättre förslag så är de välkomna!

Bashs tolkning sker redan när filen läses in, och variabeln ska få innehållet exempelvis `Europe/Stockholm` och inte `$(cat /etc/timezone)`. Kontrollera detta med `printenv TZ` i skalet, som nämndes, för att se att saker fungerar som de ska. Det ska inte finnas något "subkommando" kvar att tolka för C#, vare sig det vill eller inte, om det inte sker någon väldigt märklig magi bakom kulisserna där C# själv försöker läsa in startfiler med en egen icke-POSIX-kompatibel tolk (men det låter helt osannolikt).

Det måste vara några detaljer som saknas i beskrivningen. Gamla inställningar som spökar är ett vanligt fel.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Har inte printenv-kommandot. Systemet i fråga är en väldigt stippat inbyggt system och jag har inte möjlighet att lägga in det. Jag har använt kommandona 'env' och 'export' och båda skriver ut korrekt värde på TZ:

$ env | grep TZ TZ=Europe/Stockholm $ export | grep TZ declare -x TZ="Europe/Stockholm"

Ändå gillar mono inte mina variabler..

Jag kommer nog använda mig av första lösningen du gav då den fungerar korrekt med mono. Tack för hjälpen!

Visa signatur

..:: RiJo ::..
Computer: Lenovo X300
Platform: Gentoo

Permalänk
Hedersmedlem
Skrivet av RiJo:

Har inte printenv-kommandot. Systemet i fråga är en väldigt stippat inbyggt system och jag har inte möjlighet att lägga in det.

Körs hela Bash på ett strippat inbyggt system!?

Skrivet av RiJo:

Jag har använt kommandona 'env' och 'export' och båda skriver ut korrekt värde på TZ:

$ env | grep TZ TZ=Europe/Stockholm $ export | grep TZ declare -x TZ="Europe/Stockholm"

Ändå gillar mono inte mina variabler..

Jag kommer nog använda mig av första lösningen du gav då den fungerar korrekt med mono. Tack för hjälpen!

Bra att det fungerar, men det låter fortfarande som att något är vajsing. Jag ser inte hur Mono ska kunna ha tillgång till dina startfiler när man ber om en miljövariabel. Vill du lista ut var felet ligger så bör du skapa ett minimalt exempel som uppvisar beteendet. Vill du hellre lägga tiden på annat så kan du lägga det bakom dig, men man lär sig ofta nya saker genom att undersöka "märkligheter" noggrant.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Jag misstänker som jag skrev ursprungligen att felet uppstått när jag patchade bash för shellshock. Det har fungerat tidigare, men jag upptäckte precis att det slutat fungera utan förvarning. Ska försöka nysta mer i det när jag får tid över, men i nuläget nöjer jag mig med att mono rullar med korrekta miljövariabler.

Visa signatur

..:: RiJo ::..
Computer: Lenovo X300
Platform: Gentoo

Permalänk
Hedersmedlem
Skrivet av RiJo:

Jag misstänker som jag skrev ursprungligen att felet uppstått när jag patchade bash för shellshock. Det har fungerat tidigare, men jag upptäckte precis att det slutat fungera utan förvarning. Ska försöka nysta mer i det när jag får tid över, men i nuläget nöjer jag mig med att mono rullar med korrekta miljövariabler.

Det låter inte helt omöjligt att det skulle vara shell shock-relaterat då det berörde exekvering av variabelinnehåll, men jag skulle seriöst se över patchen som applicerades om den hade denna följd . Risken är stor att patchen inte gjorde vad den trodde att den gjorde; spontant ser det nästan ut som att den gör en sorts motsats till det som var tänkt, ifall den nu internt lagrar "$(cat /etc/localtime)" som det bokstavliga variabelinnehållet men exekverar innehållet automatiskt varje gång den visas i skalet.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.