Преобразовать следующий скрипт bash в sh - PullRequest
0 голосов
/ 06 января 2020

У меня есть этот скрипт:

#!/bin/sh
while IFS= read -r -d "" f; do
    ary+=("$f")
done < <(find ~/project/jobs -maxdepth 1 -mindepth 1 -type d -not -name "utils" -printf "\"%f\"\0")

(IFS=","; echo "[${ary[*]}]")

В нем должен быть указан список папок верхнего уровня my_folder, кроме того, который называется exclude. Это сделано в bash, но у меня нет bash на компьютере, на котором я его выполняю.

В результате чего выдается ошибка:

( В строке 3) Синтаксическая ошибка: слово неожиданное (ожидание ")")

Я хотел бы преобразовать его в sh, чтобы иметь возможность выполнить его.

I положить его на https://www.shellcheck.net/

и он дал мне ошибки:

Line 4:
while IFS= read -r -d "" f; do
                   ^-- SC2039: In POSIX sh, read -d is undefined.

Line 5:
    ary+=("$f")
    ^-- SC2039: In POSIX sh, += is undefined.
         ^-- SC2039: In POSIX sh, arrays are undefined.

Line 6:
done < <(find ~/project/jobs -maxdepth 1 -mindepth 1 -type d -not -name "utils" -printf "\"%f\"\0")
       ^-- SC2039: In POSIX sh, process substitution is undefined.

Line 8:
(IFS=","; echo "[${ary[*]}]")
                 ^-- SC2039: In POSIX sh, array references are undefined.

Есть ли способ преобразовать его в sh? Как бы я поступил.

Ответы [ 2 ]

2 голосов
/ 06 января 2020

Вам на самом деле не нужно find для этого вообще. Поскольку POSIX не поддерживает произвольные массивы, вы можете использовать позиционные параметры на их месте.

#!/bin/sh

set --   # Clear the positional parameters
cd ~/project/jobs

for d in */; do
  [ "$d" = "utils/" ] && continue
  set -- "$@" "\"${d%/}\""
done

(IFS=","; printf '[%s]\n' "$*")

Если сценарий собирается завершиться немедленно, вы можете убрать круглые скобки, так как не будет никаких Вред в настройке IFS глобально.


Поскольку кажется, что вы пытаетесь сгенерировать JSON, я бы порекомендовал следующее, если установка jq вообще возможна:

cd ~/project/jobs
jq -n --args '$ARGS.positional | select(.!="utils/") | map(rtrimstr("/"))' */
1 голос
/ 06 января 2020

Если мы просто хотим преобразовать оригинальный скрипт, вот он:

#!/bin/sh
find ~/project/jobs -maxdepth 1 -mindepth 1 -type d -not -name "utils" -printf "\"%f\"\n" | { \
sep=
while read -r f; do
    ary="$ary$sep$f"
    sep=,
done
echo "[$ary]"
}

Объясните

Вместо подстановки процесса мы используем трубопровод (|) .

Также мы должны сгруппировать while-l oop с последним эхом.

...