Очень простой экстрактор именованных аргументов для Bash:
#!/bin/bash
getargs()
{
local out=""
for argname in "$@"; do
out="${out}local $argname=\$1; shift;"
done
printf "%s" "$out"
}
testfun()
{
eval $(getargs a b c)
printf "a = %s, b = %s, c = %s\n" "$a" "$b" "$c"
}
testfun "$@"
Поскольку мы хотим, чтобы аргументы были локальными переменными в динамической области действия функции testfun
, getargs
не может быть вызовом функции. Скорее, getargs
— это крошечный компилятор , который переводит спецификацию аргумента, подобную a b c
, в синтаксис оболочки , генерируя код, который в противном случае мы добавили бы вручную, чтобы получить позиционный аргумент. в локальные переменные.
Например, вывод
getargs a b c
исходный код:
local a=$1; shift;local b=$1; shift;local c=$1; shift
когда мы eval
это делаем, оно делает то, что кажется. В контексте вызывающего объекта он получает первые три позиционных аргумента в a
, b
и c
, перемещая их из списка аргументов.
Теперь мы можем перейти на следующий уровень и добавить «прибамбасы».
Во-первых, сгенерированный код может проверять наличие ровно трех аргументов и диагностировать.
Мы могли бы поддерживать необязательные аргументы:getargs a b : c
(или что-то еще )может означать, что a
и b
являются обязательными, но c
является необязательным. Мы также могли бы поддерживать конечные аргументы:getargs a b : c. d
и генерировать код, который получает первые два аргумента (, которые необходимы ), в локальные переменные a
и b
. Затем, если присутствует третий аргумент, он переходит в c
.Любые аргументы после этого переходят в d
, который является массивом Bash.
Я оставлю это в качестве упражнения.
Очень жаль, что в оболочке нет макроса -времени расширения. Большим недостатком этого является то, что код генерируется каждый раз при вызове функции, даже если он полностью статичен.
Вы можете написать какой-нибудь препроцессор (, например. в Awk )для преобразования некоторого вида синтаксического сахара именованной функции в обычный код оболочки.
Выполните следующие шаги:
/etc/systemd/user
. Выполните mv /etc/systemd/system/Testing1.service /etc/systemd/user/
для этого. systemctl --user start Testing1.service
из своей учетной записи пользователя (, а не root ), чтобы запустить службу. Пояснениеsystemd имеет два режима работы: системный режим и пользовательский режим . Системный режим запускается до входа пользователя в свою сессию, поэтому графической сессии в этот момент нет. FreeFileSync и ReadTimeSync требуется доступ к графическому X11 дисплею, поэтому они не могут работать через системный режим . В пользовательском режиме , systemd знает о пользовательском графическом сеансе и использует его(только в том случае, оболочка, выполняющая команду, принадлежит пользователю и его графическому окружению ). Более подробную информацию можно найти в ArchWiki или на StackOverflow .