Основное различие между install
и cp
состоит в том, что если целевой файл уже существует, install
сначала отключает его.
Это различие не указано на страницах руководства. Вещи, перечисленные в других ответах, также имеют значение - обе программы имеют разные параметры, а также GNU install
имеет разные параметры, чем BSD install
, поэтому переносимые файлы Makefile ограничены общим подмножеством.
Почему удаление связи (которое также может быть выполнено с помощью rm
до cp
) имеет значение? Если у вас есть файл с двумя жесткими ссылками и вы измените его с помощью одной из жестких ссылок, он также будет изменен в другом месте файловой системы. Но если вы сначала удалите одну из жестких ссылок и замените ее измененным файлом, в другом месте сохранится исходная версия.
Более вероятный сценарий состоит в том, что вы обновляете программу или библиотеку во время ее использования. Если двоичный файл сначала отсоединить, это не повлияет на работающую программу. Вот хороший пост с более подробной информацией: http://en.chys.info/2009/05/install-vs-cp-and-mmap/
Uso de printf
y una entrada delimitada xargs
compatible con nul -:
printf -- '-f\0%s\0' important-files/*.txt | xargs -0 prog
printf
repite la cadena de formato sobre los argumentos, por lo que para cada nombre de archivo en la expansión del globo, imprimirá -f
y el nombre de archivo separados por el carácter nulo. xargs
luego lee esto y lo convierte en argumentos para prog
. El --
necesario ya que algunas implementaciones de printf
tienen problemas con un -
inicial en la cadena de formato. Alternativamente, el -
se puede reemplazar con \055
, que es estándar.
El mismo principio que la respuesta de Rakesh , pero usando la expansión comodín directamente.
Con bash, prueba:
args=()
for f in important-files/*.txt
do
args+=(-f "$f")
done
prog "${args[@]}"
Tenga en cuenta que esto funcionará no solo con nombres de archivo que contengan espacios en blanco, sino también con nombres de archivo que contengan comillas simples o dobles o incluso saltos de línea.
Para un uso interactivo fácil, defina una función:
progf() { args=(); for f in "$@"; do args+=(-f "$f"); done; prog "${args[@]}"; }
Esta función se puede utilizar de la siguiente manera:
progf important-files/*.txt
Para que la definición de la función sea permanente, colóquela en su archivo ~/.bashrc
.
Uno. El método para hacer esto es con el dúo GNU find/xargs:
cd important-files && \
find. -name '*.txt' -printf '-f\0%p\0' | xargs -0 -r prog
Como thrig ya mencionado en un comentario:
zsh -c 'prog *.txt(P:-f:)'
Esto usa el calificador global P
que antepone una palabra separada a cada coincidencia global. Como casi todos los calificadores globales de zsh, bash no tiene nada similar.
Si desea completar prog
, ejecute zsh
de forma interactiva y luego escriba prog *.txt(P:-f:)
. La primera vez que ejecute zsh de forma interactiva, le pedirá que establezca una configuración. Si no le importa zsh, elija la opción para dejar un espacio en blanco.zshrc
(pero luego se perderá algunas funciones de zsh que deben activarse explícitamente )o elija 1
y vaya a través de los menús para active los valores predeterminados recomendados.
zsh
ahora tiene un calificador global P
para eso .
Para versiones anteriores, siempre puede usar:
f=(*.txt)
prog -f$^f
$^f
habilita la opciónrcexpandparam
para la expansión de $f
, donde las matrices se expanden en un estilo similar al del shell rc
.
Enrc
(ozsh -o rcexpandparam
):
f=(*.txt)
prog -f$f
Se expande a prog -fa.txt -fb.txt
, un poco como si hubiera escrito en csh (u otros shells que admitan la expansión de llaves):prog -f{a.txt,b.txt}
.
(tenga en cuenta que es diferente de *.txt(P:-f:)
en que el nombre del archivo está pegado a la opción -ffile.txt
en lugar de pasar dos argumentos-f
file.txt
. Muchos comandos, incluidos todos aquellos que usan la API estándar getopt()
para analizar opciones, admiten el paso de argumentos a opciones )en ambos sentidos.
fish
también expande arreglos como ese:
set f *.txt
prog -f$f
En bash
, puedes emularlo con:
f=(*.txt)
prog "${f[@]/#/-f}"
Conksh93
:
f=(*.txt)
prog "${f[@]/*/-f\0}"
Para que -f
y los file.txt
correspondientes se pasen como argumentos separados, otra opción con zsh
usando su operador de compresión de matriz:
o=-f f=(*.txt); prog ${o:^^f}
Podría ampliar eso para su opción -g
. Suponiendo que hay un número par de archivos txt
:
o=(-g '') f=(*.txt); prog ${o:^^f}
Pasaría -g
opciones con dos archivos a la vez. Similar a lo que obtendrías con:
printf -- '-g\0%s\0%s\0' *.txt | xargs -r0 prog
POSIXly, siempre puede definir una función como:
prog_f() (
for i do
set -- "$@" -f "$i"
shift
done
exec prog "$@"
)