Этот факт не позволит вам вставить {}
внутри существующей опции -exec
и / или -execdir
. Замена выполняется с помощью простого strncpy ()
. exec
/ execdir
выполняется внутри GNU-find (который я использую в качестве ссылки) через bc_push_arg
. Для формы {} +
у нас есть:
/* "+" terminator, so we can just append our arguments after the
* command and initial arguments.
*/
execp->replace_vec = NULL;
execp->ctl.replace_pat = NULL;
execp->ctl.rplen = 0;
execp->ctl.lines_per_exec = 0; /* no limit */
execp->ctl.args_per_exec = 0; /* no limit */
/* remember how many arguments there are */
execp->ctl.initial_argc = (end-start) - 1;
/* execp->state = xmalloc(sizeof struct buildcmd_state); */
bc_init_state (&execp->ctl, &execp->state, execp);
/* Gather the initial arguments. Skip the {}. */
for (i=start; ictl, &execp->state,
argv[i], strlen (argv[i])+1,
NULL, 0,
1);
}
Он просто добавляет все в конце, так как у вас не может быть более одного экземпляра {}
в {} +
форма.А для {};
у нас есть:
/* Semicolon terminator - more than one {} is supported, so we
* have to do brace-replacement.
*/
execp->num_args = end - start;
execp->ctl.replace_pat = "{}";
execp->ctl.rplen = strlen (execp->ctl.replace_pat);
execp->ctl.lines_per_exec = 0; /* no limit */
execp->ctl.args_per_exec = 0; /* no limit */
execp->replace_vec = xmalloc (sizeof(char*)*execp->num_args);
/* execp->state = xmalloc(sizeof(*(execp->state))); */
bc_init_state (&execp->ctl, &execp->state, execp);
/* Remember the (pre-replacement) arguments for later. */
for (i=0; inum_args; ++i)
{
execp->replace_vec[i] = argv[i+start];
}
Итак, у нас есть execp-> ctl.replace_pat = "{}";
. Все это находится в parser.c
Вышеупомянутое заменяется следующим образом:
size_t len; /* Length in ARG before `replace_pat'. */
char *s = mbsstr (arg, ctl->replace_pat);
if (s)
{
len = s - arg;
}
else
{
len = arglen;
}
if (bytes_left <= len)
break;
else
bytes_left -= len;
strncpy (p, arg, len);
p += len;
arg += len;
arglen -= len;
В bc_do_insert ()
в buildcmd.c
.
Так что нет никакого способа избежать {}
. Тем не менее, некоторые версии find не заменяют {} / foo
, а заменяют только сам {}
, поэтому вы можете использовать две разные версии find вместе с -exec sh -c 'someCommad {}'
.
Предполагая, что gfind
- это GNU-find, а afind
- это AIX, вы, вероятно, сможете найти:
afind . -type d -execdir test -f foo.jpg \
-exec sh -c 'gfind . -name "*.m4a" -exec someCommand {} \;' \;
Но это было бы ужасным взломом.
Проблема, с которой вы столкнулись, заключается в том, что вы выполняете подстановку для получения всех файлов определенного типа в каталоге. Другими словами, вы сначала находите каталог и объединяете все файлы этого каталога в одну единую командную строку .
Это проблема, которую решает -execdir
. Он запустит команду в каталоге, содержащем найденный файл. Например:
$ mkdir -p a/a b/b c/c d e
$ touch a/a/foo.m4a b/b/foo.m4a
$ touch a/a/bar.m4a b/b/bar.m4a c/c/foobar.m4a
$ touch a/a/yay.jpg c/c/yay.jpg
$ find . -type f -name '*.m4a' -execdir test -e yay.jpg \; \
-execdir echo someCommand --arg yay.jpg {} +
someCommand --arg yay.jpg ./foobar.m4a
someCommand --arg yay.jpg ./bar.m4a ./foo.m4a
Более того, я использую форму {} +
вместо формы {};
для exec
. Это поместит все найденные файлы (в каталоге, в котором они работают) в одну командную строку.
Обратите внимание, что команда не запускалась в b / b
, потому что test -e
предотвратил это.
Какой у вас разделитель winbind в smb.conf? По умолчанию это +, поэтому для входа в систему это: домен+пользователь.
Так что, если вы хотите, вы можете переключить его на \, но я не уверен, что он не используется где-то еще.