grep сбивается с толку из-за имен файлов с тире

Когда rsync считает, что обращается как к источнику, так и к месту назначения на одном и том же хосте, и не использует инкрементную передачу. Вместо этого он просто копирует весь файл.

Такова ситуация в вашем случае.В результате ваша вторая команда копирует file.so ~ new через вашу плавкую ссылку ssh на локальный хост, а затем немедленно копирует его обратно.

Что-то не так с этим?

mv remote1/file.so~new remote1/file.so

Чтобы получить максимальную скорость, не пытайтесь запускать rsync поверх sshfs , а вместо этого разрешите ему разговаривать с удаленным компьютером. сервер напрямую (через ssh ). Затем вы можете использовать простой вариант:

rsync -av local/file.so remote:path/to/file.so

Новый файл не будет установлен, пока он не будет полностью скопирован, и вы можете использовать старую библиотеку в качестве основы для новой.

5
16.05.2017, 01:01
3 ответа

В дополнение к ответу Ромео обратите внимание, что

grep pattern --whatever

требуется POSIX для поиска шаблона в файле -- независимо . Это связано с тем, что никакие параметры не должны распознаваться после аргументов, не являющихся параметрами (здесь шаблон).

GNU grep в этом случае не соответствует POSIX. Его можно сделать совместимым, передав переменную окружения POSIXLY_CORRECT (с любым значением) в его окружение.

Это относится к большинству утилит и утилит GNU, использующих GNU или совместимую реализацию getopt()/getopt_long() для разбора аргументов командной строки.

Существуют очевидные исключения, такие как env, где env VAR=x grep --version дает вам версию grep, а не env. Другим заметным исключением является оболочка GNU (bash), где ни интерпретатор, ни какая-либо из его встроенных функций не принимают параметры после аргументов, не являющихся параметрами. Даже его getopts не могут анализировать опции способом GNU.

В любом случае, POSIXLY_CORRECT не спасет вас, если вы сделаете

grep -e pattern *.js

(здесь шаблон не является необязательным аргументом, он передается как аргумент в -e, поэтому после этого разрешены дополнительные параметры).

Поэтому всегда полезно помечать конец опций символом --, если вы не можете гарантировать, что последующее не будет начинаться с - (или + с некоторыми инструментами):

grep -e pattern -- *.js
grep -- pattern *.js

или используйте:

grep -e pattern ./*.js

(обратите внимание, что grep -- шаблон * не поможет вам, если есть файл с именем -, а grep pattern ./* будет работать.grep -e "$pattern" следует использовать вместо grep "$pattern" в случае $pattern может начинаться с -).

В середине 90-х годов была предпринята попытка bash указать getopt(), какие аргументы (как правило, получаемые в результате расширения глобуса) не должны рассматривались как параметры (через переменную окружения __GNU_nonoption_argv_flags_), но они были удалены, поскольку вызывали больше проблем, чем решали.

9
27.01.2020, 20:31

Вы можете попробовать опцию grep, которая сообщает «конец параметров»

grep -- <string> <filename>

Это сообщит grep игнорировать следующие дефисы как параметры и передавать их как следующие элементы в командной строке

6
27.01.2020, 20:31

Ваше решение с find,

find . | while read f; do grep MYSTRING "$f"; done

может быть улучшено:

find . -maxdepth 1 -type f -exec grep -H "MYSTRING" {} +

В этом нет ничего "ненадежного".

Это решает проблемы с тире в имени файла, так как find вызывает grep с именем файла, перед которым стоит путь ./.

Два других решения заключаются в том, чтобы отделить параметры от имени файла, используя -- в командной строке (что укажет процедуре синтаксического анализа командной строки, что больше нет параметров для анализа) или указать абсолютный или относительный путь к файлу.

2
27.01.2020, 20:31

Теги

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