Как использовать функцию bash, определенную в вашем .bashrc, с помощью find -exec
my.bashrc имеет следующую функцию
function myfile {
file $1
}
export -f myfile
он отлично работает, когда я вызываю его напрямую
[email protected]:~$ myfile out.ogv
out.ogv: Ogg data, Skeleton v3.0
он не работает, когда я пытаюсь вызвать его через exec
[email protected]:~$ find ./ -name *.ogv -exec myfile {} \;
find: `myfile': No such file or directory
Есть ли способ вызвать bash script функции с exec?
Любая помощь приветствуется.
Обновление:
Спасибо за ответ Джим.
Но это именно то, чего я хотел избежать в первую очередь, так как у меня есть много функций полезности, определенных в моих сценариях bash, я хотел использовать их с другими полезными командами, такими как find -exec.
Я полностью понимаю вашу точку зрения, но find может запускать исполняемые файлы, он не знает, что переданный аргумент является функцией, определенной в script.
Я получаю ту же ошибку, когда пытаюсь выполнить exec, находится в приглашении bash.
$ exec myfile out.ogv
Я надеялся, что может быть какой-то опрятный трюк, которому exec может дать некоторую гипотетическую команду вроде "bash -myscriptname -myfunctionname".
Думаю, я должен попытаться найти способ bash script как можно быстрее и запустить его с помощью exec.
Ответы
Ответ 1
Вы можете получить bash для запуска функции, поместив команду в bash StdIn:
bash$ find ./ -name *.ogv -exec echo myfile {} \; | bash
Вышеприведенная команда будет работать для вашего примера , но вам нужно обратить внимание на то, что все команды "myfile...
" генерируются сразу и отправляются в один процесс bash.
Ответ 2
find ./ -name *.ogv -exec bash -c 'myfile {}' \;
Ответ 3
Мне удалось запустить его, возможно, более элегантно, как:
function myfile { ... }
export -f myfile
find -name out.ogv -exec bash -c '"[email protected]"' myfile myfile '{}' \;
Обратите внимание, что myfile
задается дважды. Первый - параметр $0
script (и в этом случае он может быть в основном любым). Второй - имя запускаемой функции.
Ответ 4
$ cat functions.bash
#!/bin/bash
function myecho { echo "[email protected]"; }
function myfile { file "[email protected]"; }
function mycat { cat "[email protected]"; }
myname=`basename $0`
eval ${myname} "[email protected]"
$ ln functions.bash mycat
$ ./mycat /etc/motd
Linux tallguy 2.6.32-22-core2 ...
$ ln functions.bash myfile
$ myfile myfile
myfile: Bourne-Again shell script text executable
$ ln functions.bash myecho
$ myecho does this do what you want\?
does this do what you want?
$
где, конечно, функции могут быть более сложными, чем мои примеры.
Ответ 5
Я не думаю, что find
может это сделать, так как сама команда find
, выполняющая
команда, а не оболочка, в которой вы сейчас работаете... поэтому bash функции или псевдонимы
там не будет работать. Если вы возьмете определение своей функции и превратите ее в отдельную
bash script называется myfile
, сделать его исполняемым и установить его на вашем пути где-то,
find
должен поступать правильно.
Ответ 6
даже simpiler
function myfile { echo $* ; }
export -f myfile
find . -type f -exec bash -c 'myfile "{}"' \;
Ответ 7
Сценарии дочерней оболочки, похоже, поддерживают родительские функции, поэтому вы можете сделать script аналогичный этому:
'runit.sh'
#! /bin/bash
"[email protected]"
то do find -name out.ogv -exec ./runit.sh myfile '{}' \;
и это работает!:)
Ответ 8
Спасибо Жоао. Это похоже на очень умное и элегантное решение. Незначительная проблема заключалась в том, что сначала мне нужно было запустить script для запуска функции myfile, например. Я позаимствовал из вашего предложения и сделал свой runint.sh следующим образом
#!/bin/bash
script_name=$1
func_name=$2
func_arg=$3
source $script_name
$func_name $func_arg
Теперь я могу запустить его следующим образом
$ find ./ -name *.ogv -exec ./runit.sh ~/.bashrc myfile {} \;
./out.ogv: Ogg data, Skeleton v3.0
В противном случае я получал
$ find ./ -name *.ogv -exec ./runit.sh myfile {} \;
./runit.sh: 1: myfile: not found
В любом случае спасибо большое.