Ошибка сценария Bash со строками с путями, которые имеют пробелы и подстановочные знаки

Это связано с отладкой:

(от man gcc)

- g Производят отладочную информацию в собственном формате операционной системы (удары, COFF, XCOFF, или ЗАТМИТЕ 2). GDB может работать с этой отладочной информацией.

Можно выполнить отладчик на программе без отладочной информации в нем, но это похоже на попытку найти ключи в темноте. Например, Вы не можете установить точки останова:

(gdb) break 6
No symbol table is loaded.

Это - большая стычка.

25
22.09.2014, 01:40
4 ответа

Внутри кавычек, * не будет расширяться до списка файлов. Чтобы использовать такой подстановочный знак успешно, он должен быть вне кавычек.

Даже если подстановочный знак раскрылся, выражение «$ {FILES}» привело бы к единственной строке, а не к списку файлов.

Один из подходов, который мог бы работать:

#!/bin/bash
DIR="/home/john/my directory/"
for f in "$DIR"/*.txt
do
  echo "${f}"
done

В приведенном выше примере имена файлов с пробелами или другими сложными символами будут обрабатываться правильно.

Более продвинутый подход может использовать массивы bash:

#!/bin/bash
FILES=("/home/john/my directory/"*.txt)
for f in "${FILES[@]}"
do
  echo "${f}"
done

В этом случае FILES - это массив имен файлов. Сквозные скобки, окружающие определение, делают его массивом. Обратите внимание, что * находится вне кавычек. Конструкция "$ {FILES [@]}" - это особый случай: она расширяется до списка строк, где каждая строка является одним из имен файлов. Имена файлов с пробелами или другими сложными символами будут обрабатываться правильно.

33
27.01.2020, 19:40

Когда вы хотите обработать набор файлов, вы считаете, что в их имени может быть пробел или другой scape код будет там, поэтому перед началом вашего процесса, например, для цикла или найти команду установите IFS bash env переменную в :

IFS=$(echo -en "\n\b")
-1
27.01.2020, 19:40

Хотя использование массивов, как показывает Джон1024, имеет гораздо больший смысл, здесь также можно использовать оператор split+glob (оставляя скалярную переменную без кавычек).

Так как вам нужна только глобусная часть этого оператора, то необходимо отключить часть split:

#! /bin/sh -
# that also works in any sh, so you don't even need to have or use bash

file_pattern="/home/john/my directory/*.txt"
# all uppercase variables should be reserved for environment variables

IFS='' # disable splitting

for f in $file_pattern # here we're not quoting the variable so
                       # we're invoking the split+glob operator.
do
  printf '%s\n' "$f" # avoid the non-reliable, non-portable "echo"
done
7
27.01.2020, 19:40

Что вы можете сделать, так это оставить вне кавычек только подстановочные знаки.
Что-то вроде:
для a в "файлах с пробелами" *".txt"
делать
обработка
сделано
Если сами подстановочные знаки расширяются до пробелов, вам не нужно использовать подход «файл в строке», например, использовать ls -l для создания списка файлов и использовать bash read для получения каждого файла.

1
27.01.2020, 19:40

Теги

Похожие вопросы