Зацикливание каталогов и работа с файлами в скрипте bash - PullRequest
0 голосов
/ 28 июня 2018

У меня есть скрипт /home/user/me/my_script.sh, который должен зацикливаться на нескольких каталогах и обрабатывать файлы. Мой текущий рабочий каталог - / home / user / me. Вызов ls -R дает:

/ проекты:.

dir1 dir2 dir3

.

/ проекты / dir1:

image1.ntf points2.csv image1.img image1.hdr

.

/ проекты / dir2:

image2.ntf points2.csv image2.img image2.hdr

.

/ проекты / dir3:

image3.ntf points3.csv image3.img image3.hdr

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

#! /bin/bash -f
for $dir in $1*
do
  echo $dir
  set cmd = `/home/tools/tool.sh -i $dir/*.ntf -flag1 -flag2 -flag3 opt3`
  $cmd
done

Вот как он запускается (из cwd / home / user / me) и результат:

bash-4.1$ ./myscript.sh projects/
projects/*
bash-4.1$

Это не ожидаемый результат. Ожидаемый результат:

bash-4.1$ ./myscript.sh projects/
projects/dir1
[output from tool.sh]
projects/dir2
[output from tool.sh]
projects/dir3
[output from tool.sh]
bash-4.1$

Что должно произойти, сценарий должен перейти в первый каталог, найти файл * .ntf и передать его в tool.sh. В этот момент я бы начал видеть результаты этого инструмента. Я запустил инструмент для одного файла:

bash-4.1$ /home/tools/tool.sh -i /home/user/me/projects/dir1/image1.ntf -flag1 -flag2 -flag3 opt3
[expected output from tool. lengthy.]
bash-4.1$

Я пробовал синтаксис, найденный здесь: Как перебирать каталоги в Linux? и здесь: Зацикливать каталоги в Bash

for $dir in /$1*/
do ...

Результат:

bash-4.1$ ./myscript.sh projects/
/projects/*/

И

for $dir in $1/*
do ...

Результат:

bash-4.1$ ./myscript.sh projects
projects/*

Я не уверен, сколько других итераций подстановочных знаков и косых черт я могу придумать. Какой правильный синтаксис?

1 Ответ

0 голосов
/ 28 июня 2018

Во-первых, вы должны убрать флаг -f в своем шебанге, потому что это совершенно означает:

$ man bash
[…]
        -f      Disable pathname expansion.

Во-вторых, есть несколько типичных шаблонов ошибок: пробелы отсутствуют вокруг переменных (пишите "$dir", чтобы справиться с именами каталогов, содержащих пробелы), вместо этого в вашей строке for (запись for dir in "$1"*) есть ложный $ строка set неверна (set - это встроенная оболочка, используемая только для изменения конфигурации оболочки, например, set -x), согласно вашему ответу на вопрос @ ghoti кажется, что строка $cmd ненужным. Кроме того, синтаксис обратных кавычек устарел и мог быть заменен на cmd=$(/home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3).

Это приведет к следующему сценарию:

#!/bin/bash
for dir in "$1"*
do
  [[ -d "$dir" ]] || continue  # only consider existing folders
  printf "%s=%q\n" dir "$dir"
  /home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3
done

Кроме того, я бы рекомендовал всегда запускать статический анализатор ShellCheck в ваших скриптах Bash, чтобы выявлять типичные ошибки и иметь обратную связь с w.r.t. хорошие практики Если у вас есть дистрибутив Linux, его следует установить со стандартным менеджером пакетов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...