2014-11-26 8 views
8

Można trywialnie wyjście środowiska jako runnable skrypt powłoki stosującJak odtwarzać env jako runnable skrypcie

env > my_env 

... później w innym skrypcie ...

set -a 
source my_env 

ten działa w najbardziej banalnych przypadkach, ale kończy się niepowodzeniem, jeśli jakieś specjalne znaki lub spacje są w env.

Jak mogę naprawić powyższy skrypt, aby działał z takimi materiałami jak a='"'"'"?

+1

Uruchomienie tego skryptu nie zrobić bardzo dużo, choć biorąc pod uwagę jak najszybciej jak to się robi działa to wychodzi, a środowisko jego rodzica nie zmienia się nieco. 'source my_env' ma więcej sensu, ale to nie wymaga' chmod + x'. –

+0

dobry punkt usuwania + x jako jego szumy –

Odpowiedz

4

Zastosowanie set zamiast env:

○ → set | grep LESS 
LESS=-R 
LESSCLOSE='/usr/bin/lesspipe %s %s' 
LESSOPEN='| /usr/bin/lesspipe %s' 

○ → env | grep LESS 
LESS=-R 
LESSOPEN=| /usr/bin/lesspipe %s 
LESSCLOSE=/usr/bin/lesspipe %s %s 

Dzięki this similar question możemy to zrobić, aby uzyskać zmienne WŁAŚNIE środowiskowych następująco:

○ → (set -o posix; set) | grep LESS 
LESS=-R 
LESSCLOSE='/usr/bin/lesspipe %s %s' 
LESSOPEN='| /usr/bin/lesspipe %s' 

Spróbuj Behemoth, który powinien wydrukować tylko różnica od "nieskazitelnej" powłoki. YMMV:

diff --old-line-format='%L' --unchanged-line-format= --new-line-format= \ 
    <(bash -c 'set -o posix; set' | sort) \ 
    <(env -i bash -c 'set -o posix; set' | sort) 
4

następujących zastosowań bash na printf %q uciec wartości poprawnie niezależnie od ich treści. Gwarantuje to dosłownie dowolną możliwą wartość - cytaty, znaki nowej linii itp. - dopóki źródłem pozyskiwania powłoki jest bash i tak długo, jak używany system operacyjny obsługuje obiekt /proc/self/environ udostępniany najpierw przez system Linux w celu emisji treści środowisko jako strumień rozdzielony NUL. Używa specjalnych formularzy cytowania, takich jak: $'\n', w razie potrzeby, więc jego wyniki mogą nie być honorowane przez czystych interpreterów POSIX.

#!/usr/bin/env bash 
while IFS= read -r -d '' kvname; do 
    k=${kvname%%=*} 
    v=${kvname#*=} 
    printf '%q=%q\n' "$k" "$v" 
done </proc/self/environ 

Zauważ, że będziemy chcieli źródła wyjścia, nie uruchamiać go jako zewnętrznego pliku wykonywalnego, jeśli chcesz środowisko swojej bieżącej powłoki, aby zmienić. Jeśli nie chcesz, aby set -a przed sourcingiem, dodaj wiodący export do ciągu formatu.

+0

Po prostu wypróbowałem (zestaw -o posix; export) i wydaje mi się, że to też działa, czy to eksploduje na mnie? –

+0

Wątpię, czy potrzebujesz 'set -o posix' tam, faktycznie; Sam wywóz jest prawdopodobnie w porządku. Jedyną rzeczą, która powyższy kod jest lepszy niż rozwiązania natywnie oparte na powłoce, jest eksponowanie zmiennych środowiskowych, które * nie są * również poprawnymi zmiennymi powłoki (na przykład, gdy są ustawiane przez języki niepowiązane z nazwami innymi niż powłoki), ale sposób, w jaki się zachowują, jest ... bardzo zmienny. –

+1

@SamSaffron, ... to powiedziawszy, czytając dokumentację dla 'export' (lub, jeśli chcesz być bardziej jawna,' export -p'), nie widzę tego, by jej wyjście było bezpieczne dla powłoki. 'printf '% q'' * gwarantuje * bezpieczeństwo. Z drugiej strony, poleganie na '/ proc' gwarantuje zmniejszenie przenośności, więc to podejście zdecydowanie ma swoje pułapki, a implementacja w wersjach basha, które przeglądam, wydaje się być całkowicie bezpieczna, mimo że nie gwarantuje tego w dokumentacji . –

3

Najprostszy rozwiązanie wydaje się być

export -p > my_env