다음을 수행할 수 있는 Unix/Linux 파일 시스템이 있습니까?
- 파일이 실행 가능하면 파일을 실행하여 생성된 파일이 포함된 더미 파일을 반환합니다
stdout
(쓰기가 불가능해야 한다고 생각합니다). - 그렇지 않으면 ext4 및 친구들과 동일하게 동작하고 파일 자체를 제공합니다.
최근에 프로세스에 정보를 전달할 수 없지만 (여러 줄) 파일을 옵션으로 전달해야 하는 상황이 발생했습니다. 이 파일을 동적으로(로컬 또는 네트워크를 통해) 생성할 수 있다는 것은 나에게는 멋진 옵션처럼 보입니다.
/tmp에 파일을 생성하는 것은 옵션이 LDAP 항목의 속성에 있기 때문에 옵션이 아닙니다. 내 LDAP 항목에는 정적으로 정의된 다음과 유사한 속성 값이 포함되어 있습니다.
-fstype=cifs...,rw,credentials=FILENAME,... ://remote
이를 평가하는 프로세스에 데이터로 전달되며 FILENAME을 options에 대한 인수로 기대합니다 credentials=
. Bash나 다른 스크립트가 없습니다. LDAP에서 /tmp 파일을 동적으로 생성하는 방법을 알 수 없습니다.
제발 묻지 마세요왜나는 이것을 하고 싶다: 해결 방법으로 문제를 해결했지만 여전히 근본적인 문제에 관심이 있습니다.
물론 이런 종류의 일에는 항상 추가적인 질문이 수반됩니다. 안전하게 수행할 수 있습니까?
스티브
답변1
자, 내 말이 맞는지 살펴보겠습니다. LDAP에 일부 파일 이름을 참조하는 일부 데이터가 있습니다. 파일이 네트워크 공유에 있고, LDAP 디렉터리를 사용하는 모든 호스트에서 읽을 수 있으며, 파일 내용을 동적으로 생성하려고 한다고 가정합니다. 예를 들어 디렉토리에는 가 포함되어 있으며 credentials=/ldap/foo.cred
일부 시스템이 열리면 /ldap/foo.cred
동적 데이터를 얻습니다.
라는 프로그램이 있는 것 같습니다.스크립트 파일,ㅏFUSE(사용자 공간의 파일 시스템)구현은 사용자가 원하는 것과 거의 정확히 일치하지만 도구에 익숙하지 않고 작동 방식도 모릅니다. (@KamilMaciorowski는 댓글과 기사에서 이 내용을 언급했습니다.답변슈퍼유저에서. )
ScriptFS는 로컬 파일 시스템만 복사하되, 실행 결과를 기준으로 '스크립트'로 감지된 모든 파일을 교체하는 새로운 파일 시스템이다.
이름에서 알 수 있듯이 FUSE를 사용하면 사용자 공간 프로그램이 다른 프로그램과 마찬가지로 파일 시스템을 구현할 수 있으며 커널은 파일 시스템 처리를 담당하는 프로세스에 대한 파일 액세스 요청을 예약합니다. 이렇게 하면 임의의 동적 콘텐츠를 생성할 수 있습니다. 아마도 파일이 일반 파일로 나타나기 때문에 네트워크 공유를 통해서도 작동할 것 같지만 이에 대한 개인적인 경험은 없습니다.
보다 "전통적인" 기능 중에서 가장 가까운 기능은 명명된 파이프와 명명된 소켓입니다.
을 사용하여 생성된 명명된 파이프는 파일 시스템에 이름이 있고 여기에서 열 수 있다는 점을 제외하면 mkfifo
생성한 파이프와 유사합니다 . somecmd | grep foo
그래서 당신은 쓸 수 있습니다 mkfifo p; somecmd > p & grep foo < p
. 또는 마찬가지로 독자가 먼저 열 수 있습니다. 독자와 작가 모두 상대방이 올 때까지 차단합니다. 처음에는 이것이 원하는 대로 수행되는 것처럼 보입니다. 파이프에 쓰고 누군가가 읽기 위해 열 때 현재 출력을 제공하도록 프로그램을 예약할 수 있습니다. 그러나 파이프는 한 번만 존재하므로 동시 사용자는 동일한 스트림에 연결됩니다. 또한 테더링을 통해 어떻게 작동하는지 전혀 모릅니다. 파이프는 클라이언트 측에만 존재할 수 있으므로 양쪽 끝이 동일한 시스템에 있어야 합니다.
Unix 도메인 소켓은 파일 시스템의 이름 아래에 존재할 수도 있습니다(systemd를 실행하는 경우 아래에서 찾을 수 있습니다 /run
). 연결 시 열린 프로세스는 TCP 연결과 마찬가지로 소켓에서 수신 대기하는 프로세스에 연결됩니다. 여기서의 연결은 독립적이지만 문제는 (내가 아는 한) Unix 도메인 소켓을 열 수 없지만 open()
연결해야 한다는 것입니다 connect()
. 따라서 그렇게 할 수 없으며 cat < socket
작동하지 않습니다.
답변2
아니요. 그리고 그러한 파일 시스템은 쓸모가 없습니다.
예를 들어, sed
이 파일 시스템에 있다면 어떻게 작동할까요 ls | sed 's/a/b'
? 실행을 위해 셸이 열리지 sed
만 파일 시스템은 STDOUT 을 반환합니다 sed
. 그러나 파일 시스템에는 STDIN이 없으므로 이제 모든 것이 아무것도 하지 않고 sed
정지( sed
STDIN 대기)하거나 종료(빈 STDIN )됩니다.sed
이것은 또한 XY 문제이기도 합니다.
파일 시스템 동작을 변경하여 스크립트 문제를 해결하려고 해서는 안 됩니다.
@Arkadiusz Drabczyk가 제안한 것처럼 프로세스 교체로 문제를 해결할 수 있습니다. 예를 들어: 당신이 하고 싶은 일이 있다면
sort file1 | uniq >tmp1
sort file2 | uniq >tmp2
diff tmp1 tmp2
하지만 임시 파일을 만들 수 없거나 만들고 싶지 않으며 tmp1
다음 tmp2
을 수행할 수 있습니다.
diff <(sort file1 | uniq) <(sort file2 | uniq)
또 다른 예는 귀하의 질문과 약간 비슷해 보입니다. 파일이 있다고 가정해 보겠습니다 inputfile
.
a:b:c:d
i:j:k:l
e:f:g:h
간단한 데모 스크립트가 있습니다.
#!/bin/bash
filename=$(echo $* | sed 's/.*credentials=//;s/,.*//')
echo "The filename is: $filename"
echo "The contents is:"
cat $filename
그렇다면 당연히 다음을 수행할 수 있습니다.
./procsub.sh -fstype=cifs...,rw,credentials=inputfile,,... ://remote
출력은 다음과 같습니다:
a:b:c:d
i:j:k:l
e:f:g:h
그러나 출력을 정렬하려면 다음과 같이 할 수도 있습니다.
./procsub.sh -fstype=cifs...,rw,credentials=<(sort inputfile),,... ://remote
그러면 출력은 다음과 같습니다.
The filename is: /dev/fd/63
The contents is:
a:b:c:d
e:f:g:h
i:j:k:l
조금 더 명확해지기를 바랍니다.
답변3
의미상으로 설명하는 내용은 그다지 의미가 없습니다. FUSE로 구축하는 것은 상대적으로 간단하지만 많은 수준에서 잘못된 것 같습니다.
파일에서 잠재적으로 동적 데이터를 읽을 수 있기를 원합니다. 이는 프로그램이 수정할 수 없는 데이터를 얻을 수 있는 유일한 소스이기 때문입니다. 이 문제는 파일 시스템 파이프로 해결할 수 있습니다.
#!/bin/bash
PIPE="/tmp/credentials"
if [ ! -p "$PIPE" ] ; then
mkfifo "$PIPE"
fi
do
echo $SECRET >$PIPE
done