Очень жаль, что это не совсем ответ, но он наверняка не вписался в комментарий!
Подсказка для меня следующая:
+ paths='bad.py'
+ flake8 'bad.py'
При выполнении того же скрипта я получаю следующее:
$ bash -x lint.sh
++ git diff --name-only -r origin/master...HEAD
++ grep '.py$'
+ paths=bar.py
+ flake8 bar.py
bar.py:1:1: F821 undefined name 'hello'
bar.py:2:1: F821 undefined name 'world'
Обратите внимание, что мой вывод не содержит кавычки вокруг имени файла или назначения. bash
обычно не добавляет кавычки, если они не нужны. Это говорит мне о том, что вероятно какой-то управляющий символ в этой строке (мое лучшее предположение - либо цвета, либо \b
+ некоторые другие символы (это может быть один из немногих случаев, когда скриншот на самом деле полезно!)).
Вот один из способов, которым я смог воспроизвести ваши выводы:
mkdir -p bin
cat > bin/grep << EOF
#!/usr/bin/env bash
exec /bin/grep --color=always "\$@"
EOF
chmod +x bin/grep
# simulate having this `grep` on your path
PATH=$PWD/bin:$PATH bash -x lint.sh
(и хотя это кажется странным делом, в прошлом я помещал свои собственные grep
в ~/bin
, поэтому я мог добавить --line-buffered --color=auto
теперь, когда GREP_OPTIONS
устарела - можно ошибочно добавить --color=always
и заставить его работать ... по большей части). Сегодня я вместо этого использую псевдоним , так как даже с этим я столкнулся с острыми краями.
Вывод в этом случае совпадает с вашим выше:
$ PATH=$PWD/bin:$PATH bash -x lint.sh
++ git diff --name-only -r origin/master...HEAD
++ grep '.py$'
+ paths='bar.py'
+ flake8 'bar.py'
Но хитрый намек есть в выделении
дополнение
Хотя это не имеет отношения к вашей проблеме, возможно, есть лучший способ достичь желаемого:
# if you have GNU xargs
git diff -z --name-only origin/master...HEAD -- '*.py' | xargs --null --no-run-if-empty flake8
# if you need to be more portable (I see you're probably on macos)
git diff -z --name-only origin/master...HEAD -- '*.py' | xargs -0 flake8 /dev/null
Объяснение различных частей:
git diff -z
: выходные имена файлов с разделителями нулевых байтов. Это предотвращает соединение, если имена файлов содержат пробелы или другие специальные символы
xargs --null
: разделить входные данные на нулевые байты при разделении аргументов
xargs --no-run-if-empty
: вообще не запускать исполняемый файл, если нет аргументов (это расширение GNU)
xargs -0
: то же самое, что и xargs --null
, однако, если вы застряли с не-GNU xargs, у вас не будет доступа к длинным опциям
flake8 /dev/null
: это хитрый трюк, поскольку у bsd xargs нет опции «не бежать, если пусто», он всегда будет вызывать flake8
. Если flake8
вызывается с нулевыми аргументами, по умолчанию используется рекурсивный текущий рабочий каталог (и привязка всех ваших файлов). Помещая /dev/null
в начале, это предотвращает это поведение и вместо этого создает пустой файл!
Приложение 2, вы, возможно, захотите рассмотреть возможность использования фреймворка git hooks, чтобы справиться со всем этим для вас, я поддерживаю pre-commit , цель которого - сгладить множество неровностей вокруг git
(например, этот!).