bash работает один, но не работает при запуске на экране - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть скрипт bash, который начинается с

for d in /data/mydata/*; do
    echo $d
    filepath=$(echo $d | tr "/" "\n")
    pathArr=($filepath)       # fails here
    echo ${pathArr[-1]}

Работает нормально, когда я просто вызываю в командной строке

./run_preprocess.sh

но когда я запускаю его, используя экран

screen -dmSL run_preproc ./run_preprocess.sh

сбой в этой строке pathArr

./run_preproc.sh: 7: ./run_preproc.sh: Syntax error: "(" unexpected (expecting "done")

Что мне нужно сделать, чтобы защитить код скрипта?

1 Ответ

0 голосов
/ 04 сентября 2018

Судя по ошибке, ваш скрипт запускается с POSIX sh, а не bash. Массивы не определены в POSIX sh.

Чтобы исправить это, добавьте правильный хэш-бэнг в ваш скрипт (например, /usr/bin/env bash) или запустите скрипт напрямую с помощью интерпретатора Bash (например, /bin/bash script.sh).


Кроме того (не связанный с рассматриваемой проблемой) ваш сценарий (или опубликованный фрагмент) имеет несколько потенциальных проблем:

  • переменные должны быть заключены в кавычки, чтобы предотвратить глобализацию и разбиение слов (например, рассмотрим d - один из ваших файлов - содержащий * - echo $d будет включать список всех файлов, так как * будет быть расширен)

  • разбиение на массив с ($var) выполняется для любого символа IFS, а не только для перевода строки. IFS по умолчанию включает пробел, символ табуляции и новую строку. Рекомендуется использовать read -a или mapfile вместо ($var).

Наконец, если все, что вы пытаетесь получить, это получить последний компонент в пути (имя файла), вам следует рассмотреть возможность использования basename(1):

$ basename /path/to/file
file

или удаление подстроки синтаксис расширения параметра Bash:

$ path=/path/to/file
$ echo "${path##*/}"
file
...