W poszukiwaniu ścieżki

Posted on Wed 08 April 2020 in Brain game, Games, Shitz • 2 min read

Ogólnopolska kwarantanna trwa, pracuję po kilkanaście godzin dziennie ale ileż można?

No ile?

W końcu trzeba się rozerwać. Dawno temu kupiłem grę pod Linuksa pt. "TIS-100". Napisał ją Zach Bart z "Zachtronics", tak ten sam który stworzył Infiniminera, na podstawie którego powstał Minecraft.

W "TIS-100" chodzi o naprawienie komputera wujka. Problem w tym, że wujkowi się zmarło, a komputer nie tylko nie przypomina "blaszaka" ale w dodatku jest popsuty.

Skrót TIS pochodzi od słów "Tessellated Intelligence System" czyli "Inteligentny system mozaikowy", guglowy tłumacz twierdzi, że "intelligence system" to "system wywiadowczy" ale ja, nie znając jeszcze końca gry, nie zakładam z góry, że wujek miał coś wspólnego z NSA.

gierka

TIS-100 składa się z wielu węzłów, z których każdy ma porty do komunikacji z sąsiednimi węzłami oraz kilka rejestrów. Wujek zbudował go do równoległego przetwarzania złożonych strumieni danych.

Ale ja nie o tym.

Stworzyłem sobie w Linuksie środowisko, którego zasad staram się ostro trzymać. W ~/bin trzymam własne (i nie tylko) skrypty, ułatwiające życie. Większość z nich ma rozszerzenia określające język powłoki lub programowania w których są napisane, i tak np. bashowe kończą się na .sh, a te w Pythonie na .py.

Jeśli skrypt uruchamia jakiś program z GUI to zasadą jest, że robię linka w /usr/local/bin z nazwą bez rozszerzenia. Czyli ~/bin/tis.sh jest podlinkowany w /usr/local/bin/tis.

I tu zaczynają się prawdziwe schody. W przypadku gry "TIS-100" oryginalny skrypt ją uruchamiający nie zadziała, gdy jest odpalany z linka.

Przyczyną błędu jest następująca linia:

declare -r CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Zmienna $CURRENT_DIR powinna wskazywać na folder w którym znajduje się skrypt start.sh, uruchamiający grę. Jednak pod odpaleniu z /usr/local/bin/tis zmienna będzie zawierała ciąg "/usr/local/bin".

Szukając uniwersalnego rozwiązania (bo z palca to każdy głupi umie), natknąłem się na test z Githuba:

https://gist.github.com/gvlx/0adfb1137937ad443df2eeaa73dc0ba7

Skrypt sugeruje jako najlepsze rozwiązanie dla mojego Debiana 10: ``test7``, czyli użycie cd -P wraz z pwd, ale rozwiązanie z readlinkiem również działa w moim przypadku, a wymaga mniej pisania. Wygląda tak:

declare -r CURRENT_DIR="$(cd -P "$(dirname $(readlink -f $0))" && pwd)"

Jednak wersja 7 jest uniwersalna - wg autora działa również na *niksach. Kod wygląda na skomplikowany ale to tylko pozory:

__SOURCE__="${BASH_SOURCE[0]}"
while [[ -h "${__SOURCE__}" ]]; do
    __SOURCE__=$(find "${__SOURCE__}" -type l -ls | sed -n 's/^.* -> \(.*\)/\1/p');
done;

declare -r CURRENT_DIR=$(cd -P "$( dirname "${__SOURCE__}" )" && pwd)

Co tam się dzieje:

najpierw do zmiennej SOURCE przypisana zostaje pełna ścieżka do linku, potem za pomocą finda wyszukiwany jest plik źródłowy, a sedem "wyrąbywana" jest ścieżka do niego.

Następnie dirname wycina ścieżkę do folderu, a za pomocą "cd -P" oraz pwd, rozkminiana jest rzeczywista ścieżka.

Po podmiance gra działa i mógłbym przystąpić do ratowania spuścizny po wujku ale robota czeka.

A podobno gry niczego nie uczą...