Możesz łatwo sprawdzić skrypty powłoki za pomocą ShellCheck online (dostępny również jako samodzielne narzędzie).
W takim przypadku będzie wskazywać, że instrukcja if wymaga spacji, [przed i przed ], oraz że potrzebujesz ;(lub nowego wiersza) przed thentym samym wierszem.
Kiedy to naprawisz, wyświetli się informacja, że USER_NAMEjest używany bez inicjowania czegokolwiek. Jest tak, ponieważ masz również user_namezmienną (wielkość liter ma znaczenie). To samo dotyczy PASSi pass.
Mówi ci również, abyś używał, read -raby powstrzymać się readod zniekształcania \(może to być ważne na przykład w przypadku haseł) oraz że powinieneś podwójnie cytować zmienne podczas wywoływania, sqlplusaby zapobiec przypadkowemu globalizacji nazw plików i dzieleniu słów przez powłokę (ponownie jest to ważne, jeśli hasło zawiera na przykład znaki globowania plików, takie jak *spacje).
Wcięcie kodu sprawi, że będzie on również bardziej czytelny:
#!/bin/bash
read -r -p 'please enter username: ' user_name
IFS= read -rs -p 'please enter password: ' pass
printf 'ORACLE_SID = %s\n' "$ORACLE_SID"
sid=$ORACLE_SID
if [ "$sid" = 'Test' ]; then
echo 'Cannot copy' >&2
exit 1
fi
sqlplus -s -l "$user_name/$pass@$sid" <<'SQL_END'
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
SQL_END
Tutaj umożliwiłem także używanie haseł z wiodącymi lub końcowymi znakami spacji, tymczasowo ustawiając IFSpusty ciąg znaków do odczytu hasła read.
Zmieniono również logikę, aby ratować, jeśli $ORACLE_SID/ $sidis Test. Pozwala to uniknąć posiadania głównej części operacyjnej skryptu w ifgałęzi.