Muszę utworzyć plik konfiguracyjny dla własnego skryptu: tutaj przykład:
scenariusz:
#!/bin/bash
source /home/myuser/test/config
echo "Name=$nam" >&2
echo "Surname=$sur" >&2
Treść /home/myuser/test/config
:
nam="Mark"
sur="Brown"
to działa!
Moje pytanie: czy to jest właściwy sposób, aby to zrobić, czy istnieją inne sposoby?
bash
shell
shell-script
Pol Hallen
źródło
źródło
abcde
robi to również w ten sposób i jest to dość duży program (dla skryptu powłoki). Możesz to zobaczyć tutaj .Odpowiedzi:
source
nie jest bezpieczny, ponieważ wykona dowolny kod. Może to nie stanowić problemu, ale jeśli uprawnienia do plików są niepoprawne, osoba atakująca z dostępem do systemu plików może wykonać kod jako użytkownik uprzywilejowany przez wstrzyknięcie kodu do pliku konfiguracyjnego załadowanego w inny sposób zabezpieczonym skryptem, takim jak skrypt inicjujący.Jak dotąd najlepszym rozwiązaniem, jakie udało mi się zidentyfikować, jest niezdarne rozwiązanie na nowo:
myscript.conf
Przy użyciu
source
uruchomiłoby się toecho rm -rf /
dwukrotnie, a także zmieniłoby działającego użytkownika$PROMPT_COMMAND
. Zamiast tego wykonaj następujące czynności:myscript.sh (Bash 4)
myscript.sh (kompatybilny z Mac / Bash 3)
Proszę odpowiedzieć, jeśli znajdziesz w moim kodzie lukę w zabezpieczeniach.
źródło
*
poprawnie obsługiwać danych wejściowych, ale co w Bash dobrze obsługuje tę postać?my\\password
Oto czysta i przenośna wersja, która jest kompatybilna z Bash 3 i nowszymi, zarówno na Macu, jak i Linuksie.
Określa wszystkie wartości domyślne w osobnym pliku, aby uniknąć potrzeby ogromnej, zaśmieconej, zduplikowanej funkcji konfiguracyjnej „domyślne” we wszystkich skryptach powłoki. I pozwala wybierać między czytaniem z domyślnymi awariami lub bez nich:
config.cfg :
config.cfg.defaults :
config.shlib (jest to biblioteka, więc nie ma linii shebang):
test.sh (lub dowolne skrypty, w których chcesz odczytać wartości konfiguracji) :
Objaśnienie skryptu testowego:
printf
linia? Cóż, jest to coś, o czym powinieneś wiedzieć:echo
to złe polecenie do drukowania tekstu, nad którym nie masz kontroli. Nawet jeśli użyjesz podwójnego cudzysłowu, zinterpretuje flagi. Spróbuj ustawićmyvar
(inconfig.cfg
) na,-e
a zobaczysz pustą linię, ponieważecho
pomyślisz, że to flaga. Aleprintf
nie ma tego problemu.printf --
Mówi „drukuj, i niczego nie interpretować jako flagi”, a"%s\n"
mówi „formatować dane wyjściowe jako ciąg z końcowym znakiem nowej linii, a wreszcie ostateczny parametr jest wartością dla printf do pliku PDF.myvar="$(config_get myvar)";
. Jeśli masz zamiar wydrukować je na ekranie, sugeruję użycie printf, aby całkowicie zabezpieczyć się przed ciągami niezgodnymi z echem, które mogą znajdować się w konfiguracji użytkownika. Ale echo jest w porządku, jeśli zmienna podana przez użytkownika nie jest pierwszym znakiem echa, ponieważ jest to jedyna sytuacja, w której „flagi” można interpretować, więc coś w tym rodzajuecho "foo: $(config_get myvar)";
jest bezpieczne, ponieważ „foo” nie zacznij od myślnika i dlatego mówi echo, że reszta ciągu również nie jest dla niego oznaczona. :-)źródło
config.cfg.defaults
zamiast definiowania ich w momencie dzwonienia$(config_get var_name "default_value")
. tritarget.org/static/…Analizuj plik konfiguracyjny, nie wykonuj go.
Obecnie piszę w pracy aplikację, która używa niezwykle prostej konfiguracji XML:
W skrypcie powłoki („aplikacji”) robię to, aby uzyskać nazwę użytkownika (mniej więcej umieściłem ją w funkcji powłoki):
xml
Komenda jest XMLStarlet , który jest dostępny dla większości Uniksów.Używam XML, ponieważ inne części aplikacji dotyczą również danych zakodowanych w plikach XML, więc było to najłatwiejsze.
Jeśli wolisz JSON, jest
jq
łatwy w użyciu parser JSON powłoki.Mój plik konfiguracyjny wyglądałby mniej więcej w JSON:
A potem dostałbym nazwę użytkownika w skrypcie:
źródło
eval
do ustawiania wielu wartości, wówczas wykonujesz wybrane części pliku konfiguracyjnego :-).eval
niczego. Wydajność wynikająca z używania standardowego formatu z istniejącym parserem (nawet jeśli jest to narzędzie zewnętrzne) jest nieznaczna w porównaniu z odpornością, ilością kodu, łatwością użycia i łatwością konserwacji.Najczęstszym, wydajnym i poprawnym sposobem jest użycie
source
lub.
forma skrócona. Na przykład:lub
Należy jednak wziąć pod uwagę problemy związane z bezpieczeństwem, które może spowodować użycie dodatkowego pliku konfiguracyjnego pochodzącego z zewnątrz, ponieważ można wstawić dodatkowy kod. Aby uzyskać więcej informacji, w tym na temat wykrywania i rozwiązywania tego problemu, polecam zajrzeć do sekcji „Zabezpiecz to” na http://wiki.bash-hackers.org/howto/conffile#secure_it
źródło
Używam tego w moich skryptach:
Powinien obsługiwać każdą kombinację znaków, z wyjątkiem kluczy, których nie można
=
w nich mieć , ponieważ jest to separator. Wszystko inne działa.Jest to również całkowicie bezpieczne, ponieważ nie korzysta z żadnego rodzaju
source
/eval
źródło
W moim scenariuszu
source
lub.
było w porządku, ale chciałem wspierać lokalne zmienne środowiskowe (tj.FOO=bar myscript.sh
), Które mają pierwszeństwo przed zmiennymi skonfigurowanymi. Chciałem też, aby plik konfiguracyjny był edytowalny przez użytkownika i wygodny dla kogoś, kto zwykł pozyskiwać pliki konfiguracyjne, i aby był tak mały / prosty, jak to możliwe, aby nie odwracał uwagi od głównego ciągu mojego bardzo małego skryptu.Oto co wymyśliłem:
Zasadniczo - sprawdza definicje zmiennych (bez zbytniej elastyczności co do białych znaków) i przepisuje te wiersze, aby wartość została przekonwertowana na wartość domyślną dla tej zmiennej, a zmienna nie jest modyfikowana, jeśli zostanie znaleziona, tak jak
XDG_CONFIG_HOME
zmienna powyżej. Źródła tej zmienionej wersji pliku konfiguracyjnego i kontynuuje.Przyszłe prace mogą sprawić, że
sed
skrypt będzie bardziej niezawodny, odfiltrować wiersze, które wyglądają dziwnie lub nie są definicjami itp., Nie przerywają komentarzy na końcu wiersza - ale na razie jest to dla mnie wystarczające.źródło
Jest to zwięzłe i bezpieczne:
Te
-i
, zapewnia można dostać tylko od zmiennychcommon.vars
źródło
Możesz to zrobić:
źródło