Я знаю, что это уже решено для OP, но для всех, кто наткнулся на этот вопрос, это, похоже, проблема только для версии 10.11 El Capitan. Я пробовал и смог удалить файлы с этим символом в OS X 10.4 Tiger и OS X 10.10 Yosemite, поэтому он, скорее всего, работает с другими.
Лучший способ сделать это — просто поместить вашу функцию в файл сценария и вызвать сценарий как таковой:
caffeinate myfunction.sh
Содержимое myfunction.sh:
#!/bin/bash
sleep 2
убедитесь, что файл сценария исполняемый файл, иначе он выдаст вам ошибку разрешения:
chmod +x myfunction.sh
caffeinate
ожидает выполнения команды в новом процессе.
Чтобы интерпретировать функцию zsh
, вам нужна команда zsh
.
И вам нужно будет передать ей определение этой функции (, а также других функций, которые могут понадобиться ), например, с помощью:
mysleep() {
sleep 2
}
caffeinate zsh -c "$(functions mysleep);mysleep"
functions mysleep
сбрасывает определение функции mysleep
, которую мы передаем этой новой функции zsh
для интерпретации перед вызовом функции, так что zsh
, вызванная caffeinate
, заканчивается интерпретацией:
mysleep() {
sleep 2
};mysleep
Если сравнить с bash
:
mysleep() {
sleep 2
}
export -f mysleep
caffeinate bash -c "mysleep"
(, что на 2 символа короче, чем ), bash
подойдет:
execve("/path/to/caffeinate",
["caffeinate", "bash", "-c", "mysleep"],
["BASH_FUNC_mysleep%%=() { sleep 2\n}", rest-of-environment])
В то время как с zsh
мы получаем:
execve("/path/to/caffeinate",
["caffeinate", "zsh", "-c", "mysleep () {\n\tsleep 2\n};mysleep"],
[rest-of-environment])
Я вижу несколько преимуществ последнего подхода:
%
символов (, и даже если это не так, подумайте о sudo
, например ), мы не гарантируем, что caffeinate
распространит его на выполняемую команду bash
. sleep
, например, в этом примере ). bash
короче, в execve()
передается больше данных, что вносит больший вклад в ограничение E2BIG для этого системного вызова. Если вы хотите использовать среду, вы все равно можете:
FUNCS=$(functions mysleep) caffeinate zsh -c '
eval "$FUNCS";mysleep'
В случае caffeinate
здесь нам нужно только, чтобы caffeinate
выполнялся во время работы функции, не обязательно, чтобы он запускал функцию, мы можем использовать другие подходы, такие как:
mysleep | caffeinate cat
cat
будет работать до тех пор, пока работает mysleep
.mysleep
по-прежнему будет выполняться в отдельном процессе, и это влияет на стандартный вывод mysleep
.
mysleep 3> {fd}>(caffeinate cat)
решит обе проблемы.
Как и выше, это создает канал между mysleep
и cat
. Но конец канала для записи теперь находится на вновь выделенном файловом дескрипторе выше 10 (, хранящемся в $fd
), в который mysleep
обычно не записывается. Таким образом, cat
ничего не будет читать, но дождется конца -файла -в канале, что произойдет только тогда, когдаmysleep
(и все дочерние процессы, наследующие этот fd ), завершатся.