Расширение переменной Grep в "find -exec sh -c" - PullRequest
0 голосов
/ 07 марта 2019

Я написал скрипт, который просматривает текстовые документы, чтобы соответствовать словам внутри них.Ниже приведен пример, который работает и находит число 43. Далее следует скрипт, который не работает.Все, что я хочу сделать, это иметь номер 43 в качестве переменной в начале моего скрипта, но, похоже, он не расширяется должным образом.Любые идеи, как я могу иметь 43 в качестве переменной в моем сценарии, а не жестко кодировать его?

Сценарий, который работает:

find . -type f -name '*.docx' -exec sh -c '
  for file do
docx2txt "$file" 2>/dev/null - | grep -i --color "43" && printf "\033[1;32mFound in ${file}\033[0m\n"
#readlink -f "$file"
  done
' sh {} +

Сценарий, который не работает:

scan_var=43
find . -type f -name '*.docx' -exec sh -c '
  for file do
docx2txt "$file" 2>/dev/null - | grep -i --color "$scan_var" && printf "\033[1;32mFound in ${file}\033[0m\n"
#readlink -f "$file"
  done
' sh {} +

Ответы [ 3 ]

3 голосов
/ 07 марта 2019

С точки зрения безопасности, вы должны использовать export для предоставления переменных подпроцессам через среду, а не подставлять эти переменные в строки, анализируемые как код (что поддается инъекция оболочки атаки).

То есть:

export scan_var=43  ## the **only** change is to this line!

# only modifications to code below are formatting with no functional impact
# ...well, and safer printf use (to not expand format strings in filenames)
find . -type f -name '*.docx' -exec sh -c '
  for file do
    docx2txt "$file" 2>/dev/null - \
    | grep -i --color "$scan_var" \
    && printf "\033[1;32mFound in %s\033[0m\n" "$file"
  done
' sh {} +
2 голосов
/ 07 марта 2019

sh -c разветвляется подпроцесс, где переменная не видна, см. ответ Чарльза для исправления.

Еще один способ получить переменную в -exec sh -c - этоиспользуйте это как параметр.Рассмотрим

$ var=43
$ sh -c 'echo "$var"'         # Expands to nothing

$ sh -c 'echo "$1"' sh "$var"  # Gets variable value into sh -c
43

Обратите внимание, что первый параметр для sh -c после команды используется как $0 в sh -c (имя процесса).

Применяется к вашей команде:

scan_var=43
find . -type f -name '*.docx' -exec sh -c '
    scan_var=$1
    shift
    for file do
        echo docx2txt "$file" 2>/dev/null - \
            | grep -i --color "$scan_var" \
            && printf "\033[1;32mFound in ${file}\033[0m\n"
        # readlink -f "$file"
    done
' sh "$scan_var" {} +

Значение первого параметра считывается в scan_var, а затем параметр сбрасывается с помощью shift.

0 голосов
/ 07 марта 2019

Вы пытаетесь использовать переменную внутри одинарных кавычек. Настройте grep командную строку:

grep -i --color "'"$scan_var"'" && ...

Это закроет одинарную кавычку от вашего find -exec до $scan_var и запустит одинарную кавычку для остальной части кода.

...