![杀死在 nix-shell 中启动的后台进程](https://linux22.com/image/138975/%E6%9D%80%E6%AD%BB%E5%9C%A8%20nix-shell%20%E4%B8%AD%E5%90%AF%E5%8A%A8%E7%9A%84%E5%90%8E%E5%8F%B0%E8%BF%9B%E7%A8%8B.png)
我正在开发一个简单的数据科学环境带有Python
工具和数据库。当我输入时nix-shell
,我启动数据库进程。我想在退出环境时将其降速。
我该如何使用trap
并nix
实现这一目标?
答案1
我一直在使用类似以下的东西:
./shell.nix:
let
pkgs = import <nixpkgs> { };
in with pkgs; mkShell {
buildInputs = [ glibcLocales postgresql ];
shellHook = ''
export LANG=en_US.UTF-8
PGDATABASE=some-dbname \
PGDATA="$PWD/nix/pgdata" \
PGHOST="$PWD/nix/sockets" \
PGPORT="5433" \
PGUSER="$USER"
trap "'$PWD/nix/client' remove" EXIT
nix/client add
'';
}
./nix/客户端
#! /usr/bin/env bash
set -eu
client_pid=$PPID
start_postgres() {
if postgres_is_stopped
then
logfile="$PWD/log/pg.log"
mkdir -p "$PGHOST" "${logfile%/*}"
(set -m
pg_ctl start --silent -w --log "$logfile" -o "-k $PGHOST -h ''")
fi
}
postgres_is_stopped() {
pg_ctl status >/dev/null
(( $? == 3 ))
}
case "$1" in
add)
mkdir -p nix/pids touch nix/pids/$client_pid
if [ -d "$PGDATA" ]
then
start_postgres
else
pg_ctl initdb --silent -o '--auth=trust' && start_postgres && createdb $PGDATABASE
fi
;;
remove)
rm nix/pids/$client_pid
if [ -n "$(find nix/pids -prune -empty)" ]
then
pg_ctl stop --silent -W
fi
;;
*)
echo "Usage: ${BASH_SOURCE[0]##*/} {add | remove}"
exit 1
;;
esac
EXIT
如果没有其他 nix-shell 会话仍在使用数据库服务器,陷阱将关闭数据库服务器。
答案2
这只是 @ivan 关于如何在一个命令中调用多个命令的答案的附录trap
:
shellHook =
let
# NOTE These are equivalent.
#
# shellHook = shellHook =
# '' ''
# trap \ trap \
# " "
# '' echo lofa
# + '' sleep 2
# echo lofa echo miez
# sleep 2 " \
# echo miez EXIT
# '' ''
# + '' ;
# " \
# EXIT
# ''
# ;
# Helper function to achieve the same
cleanUp =
shell_commands:
''
trap \
"
${ builtins.concatStringsSep "" shell_commands }
" \
EXIT
''
;
in
cleanUp [
''
echo -n "POSTGRES CLEANUP START..."
''
( builtins.readFile ./postgres/clean-up.sh )
''
echo "END"
''
]
;
也可以看看这个帖子一个更长的例子。