Я бы использовал функцию оболочки:
composer() {
php "$PWD"/composer.phar "$@"
}
Напишите функцию оболочки -, которая будет выполняться, когда ваш скрипт завершится. В приведенном ниже примере я называю это «очисткой» и устанавливаю ловушку, которая будет выполняться на уровнях выхода, например :0 1 2 3 6
trap cleanup 0 1 2 3 6
cleanup()
{
[ -d $TMP ] && rm -rf $TMP
}
Дополнительную информацию см. в этом сообщении.
В случае временного файла ваш пример в вопросе создаст его, затем отсоединит от каталога (, сделав его «исчезнувшим» ), и когда скрипт закроет файловый дескриптор (, вероятно, после завершение ), пространство, занимаемое файлом, может быть освобождено системой. Это распространенный способ работы с временными файлами в таких языках, как C.
Насколько я знаю, невозможно открыть каталог таким же образом, по крайней мере, никоим образом, чтобы сделать каталог пригодным для использования.
Обычный способ удаления временных файлов и каталогов после завершения сценария — установка ловушки очистки EXIT
. Примеры кода, приведенные ниже, полностью избавляют от необходимости жонглировать файловыми дескрипторами.
tmpdir=$(mktemp -d)
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"; rm -rf "$tmpdir"' EXIT
# The rest of the script goes here.
Или вы можете вызвать функцию очистки:
cleanup () {
rm -f "$tmpfile"
rm -rf "$tmpdir"
}
tmpdir=$(mktemp -d)
tmpfile=$(mktemp)
trap cleanup EXIT
# The rest of the script goes here.
Ловушка EXIT
не будет выполняться при получении сигнала KILL
(, который не может быть перехвачен ), что означает, что тогда не будет выполняться очистка. Однако он будет выполняться при завершении из-за сигнала INT
или TERM
(, если работает с bash
или ksh
, в других оболочках вы можете добавить эти сигналы после EXIT
в trap
командной строки )или при обычном выходе из-за достижения конца скрипта или выполнения вызова exit
.
Вы можете войти в него, а затем удалить его, при условии, что вы не пытаетесь впоследствии использовать пути внутри него:
#! /bin/sh
dir=`mktemp -d`
cd "$dir"
exec 4>file 3<file
rm -fr "$dir"
echo yes >&4 # OK
cat <&3 # OK
cat file # FAIL
echo yes > file # FAIL
Я не проверял, но, скорее всего, та же проблема возникает при использовании openat (2 )в C с каталогом, которого больше нет в файловой системе.
Если вы root и работаете в Linux, вы можете поиграться с отдельным пространством имен и mount -t tmpfs tmpfs /dir
внутри него.
Канонические ответы (устанавливают ловушку на ВЫХОД )не работают, если ваш скрипт вынужден выполнить нечистый выход (например. с SIGKILL ); это может привести к тому, что конфиденциальные данные останутся без дела.
Обновление:
Вот небольшая утилита, которая реализует подход пространства имен. Он должен быть скомпилирован с
cc -Wall -Os -s chtmp.c -o chtmp
и заданные CAP_SYS_ADMIN
файловые возможности (как root )с
setcap CAP_SYS_ADMIN+ep chtmp
При запуске (от обычного пользователя )от имени
./chtmp command args...
он отменит совместное использование своего пространства имен файловой системы, смонтирует файловую систему tmpfs на /proc/sysvipc
, подключится к ней и запустит command
с заданными аргументами. command
не не унаследует возможности CAP_SYS_ADMIN
.
Эта файловая система не будет доступна из другого процесса, не запущенного из command
, и она волшебным образом исчезнет (со всеми файлами, которые были созданы в ней ), когда command
и ее дочерние элементы умрут, независимо от того, как это происходит. Обратите внимание, что это просто удаление пространства имен монтирования --. Между command
и другими процессами, запущенными тем же пользователем, нет жестких барьеров; они все еще могли проникнуть внутрь его пространства имен либо через ptrace(2)
, /proc/PID/cwd
, либо другими способами.
Захват "бесполезного" /proc/sysvipc
- это, конечно, глупо, но альтернативой был бы спам /tmp
пустыми каталогами, которые пришлось бы удалить или сильно усложнить эту маленькую программу форками и ожиданиями. В качестве альтернативы dir
можно изменить, например, на. /mnt/chtmp
и создать его пользователем root при установке; не делайте его настраиваемым пользователем -и не устанавливайте его на принадлежащий пользователю -путь, так как это может подвергнуть вас ловушкам символических ссылок и другим волосатым вещам, на которые не стоит тратить время.
чтмп.с
#define _GNU_SOURCE
#include <err.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mount.h>
int main(int argc, char **argv){
char *dir = "/proc/sysvipc"; /* LOL */
if(argc < 2 || !argv[1]) errx(1, "usage: %s prog args...", *argv);
argv++;
if(unshare(CLONE_NEWNS)) err(1, "unshare(CLONE_NEWNS)");
/* "modern" systemd remounts all mount points MS_SHARED
see the NOTES in mount_namespaces(7); YUCK */
if(mount("none", "/", 0, MS_REC|MS_PRIVATE, 0))
err(1, "mount(/, MS_REC|MS_PRIVATE)");
if(mount("tmpfs", dir, "tmpfs", 0, 0)) err(1, "mount(tmpfs, %s)", dir);
if(chdir(dir)) err(1, "chdir %s", dir);
execvp(*argv, argv);
err(1, "execvp %s", *argv);
}