![특정 확장자를 가진 파일을 인수로 기대하는 프로그램을 속이기 위해 프로세스 대체를 사용하시겠습니까?](https://linux55.com/image/36145/%ED%8A%B9%EC%A0%95%20%ED%99%95%EC%9E%A5%EC%9E%90%EB%A5%BC%20%EA%B0%80%EC%A7%84%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EC%9D%B8%EC%88%98%EB%A1%9C%20%EA%B8%B0%EB%8C%80%ED%95%98%EB%8A%94%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%84%20%EC%86%8D%EC%9D%B4%EA%B8%B0%20%EC%9C%84%ED%95%B4%20%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%20%EB%8C%80%EC%B2%B4%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%8B%9C%EA%B2%A0%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
제 사용 사례는 다음과 같습니다. 명령줄 유틸리티는 melt
명령줄 확장명이 포함된 파일 이름을 받아 열 수 있습니다. .melt
예를 들어 다음은 올바른 test_p.melt
파일입니다.
colour:blue
out=24
colour:red
out=48
...열어서 플레이하세요 melt test_p.melt
.
이제 문제는 .melt
파일이 주석을 지원하지 않는다는 것입니다. 주석을 지원하고 싶습니다( a가 있는 줄을 포함하여 확인할 수 없는 인수가 포함된 모든 줄에 대해 오류가 발생합니다 #
). 다음은 주석이 달린 test_c.melt
파일입니다.
# master comment here
colour:blue # this is blue!
out=24
colour:red
out=48
직접 열면 다음이 melt
제공됩니다.
$ melt test_c.melt
Failed to load "# master comment here"
...
...그리고 블루 스크린이 나타나지 않습니다.
그래서 저는 생각했습니다. 좋아요, 댓글을 달 수 있어요그래도, Bash 프로세스 대체를 사용하여 파일을 필터링 하고 애플리케이션 sed
에 제공합니다 . melt
먼저 다음을 사용해 테스트해 보세요 cat
.
$ cat <(sed 's/#.*$//' test_c.melt)
colour:blue
out=24
colour:red
out=48
... 좋아 보이네요.하지만, 다음을 사용하려고 하면 melt
내 계략이 잡힙니다 .
$ melt <(sed 's/#.*$//' test_c.melt)
Failed to load "/dev/fd/62"
Failed to load "/dev/fd/62"
기본적으로 Melt는 프로세스 교체를 위해 제공된 Bash 파이프의 파일 이름을 가져옵니다. 그러나 불행하게도 그것이 melt
파일 argv[i]
인 경우 .melt
파일 이름의 확장자를 확인해야 합니다. 프로세스가 실패합니다.
그래서 내 질문은: 이 경우 프로세스 대체를 어떻게 사용할 수 있습니까? 그러면 파이프의 파일 이름에 특정 확장자가 있습니까 .melt
? 기본적으로 대체 결과로 /dev/fd/62.melt
통과할 것으로 생각되는 파이프 파일 이름이 필요합니다.
참고: 물론 언제든지 이 작업을 수행할 수 있습니다.
sed 's/#.*$//' test_c.melt > test_c_temp.melt
melt test_c_temp.melt
...하지만 먼저 여기에 두 가지 명령이 있습니다. 반면에 한 줄짜리 파이프를 원하면 나중에 임시 파일을 삭제하는 것이 마음에 들지 않는 또 다른 문제가 발생합니다.
Bash 프로세스 교체를 통해 또는 표준 Linux 도구를 통해 이를 달성할 수 있습니까?
답변1
melt
한 가지 가능성은 파일의 수정된 복사본을 표시하는 파일 시스템을 가리키는 것입니다 .퓨즈이는 파일 시스템 드라이버를 구축하는 일반적인 방법으로, 일반 프로그램으로 구현되며 권한이 필요하지 않습니다. 가지다많은 FUSE 파일 시스템, 그리고 그 중 하나가 당신을 도울 수 있는 좋은 기회가 있습니다. 아이디어는 .melt
파일을 읽을 때 "실제" 파일을 읽지만 주석은 필터링되는 마운트 지점을 제공하는 것입니다.
스크립트 파일 시스템유망해 보입니다(하지만 한번도 사용해본 적이 없습니다). 다음과 같이 작동해야 합니다.
mkdir ~/uncommented-melt
scriptfs -p "$HOME/bin/uncomment-melt;&*.melt" ~/work ~/uncommented-melt
파일이 포함된 ~/work
트리의 루트는 어디에 있습니까?.melt
~/bin/uncomment-melt
#!/bin/sh
sed 's/#.*$//' "$1"
그런 다음 주석이 포함된 파일이 있으면 를 ~/work/test_c.melt
실행할 수 있습니다 melt ~/uncommented-melt/test_c.melt
.
유용할 수 있는 기타 FUSE 파일 시스템:
답변2
zsh
셸을 사용하면 접미사를 지정할 수 있는 =(...)
프로세스 대체 형식(파일 및 파이프 대신 임시 파일 사용 )을 사용할 수 있습니다./dev/fd/x
(TMPSUFFIX=.melt; melt =(sed 's/#.*$//' test_c.melt))
자세한 내용은 을 참조하세요 info zsh TMPSUFFIX
( info
페이지가 설치되어 있다고 가정하면 패키지를 설치해야 할 수도 있음 zsh-doc
).
답변3
글쎄요, 제 특별한 경우에는 이러한 Melt 스크립트가 명령줄 인수로 엄격하게 해석되므로 sed
OP에 있는 스크립트만으로는 문제가 해결되지 않습니다. 구성 파일을 설정할 수 있습니다). 그래서 제가 하게 된 일은 다음과 같습니다. 이는 OP 제목에서 다루는 다른 상황에서 영감을 줄 수 있습니다.
나는 마침내 이것을 사용하기로 결정했습니다. 실제로 주석이 달린 스크립트 코드가 포함된 스크립트 test.shmelt
인 파일을 생성하고, 스크립트를 편집한 후 .bash
melt
chmod +x test.shmelt
./test.shmelt
실행되면 test.melt
"정리된" 파일이 생성되고 해당 파일이 /tmp
호출됩니다 . 프로그램은 일반적 melt
으로 melt
종료 후에도 터미널에서 계속 실행되므로 SIGINT의 트랩을 통해 Ctrl-C를 누르면 이 임시 파일을 지울 수 있습니다(필수는 아님).
그게 전부입니다. 여전히 주석이 있습니다. 소스 파일에서 Melt를 빠르게 편집하고 실행할 수 있으며 나중에 사용할 수 있도록 주석이 "정리된" 파일도 있습니다.
코드는 다음과 같습니다 test.shmelt
.
#!/bin/bash
# call with: ./test.shmelt
#TMLTFILE="test.melt" # for final export
TMLTFILE="${0%%.shmelt}.melt" # for final export
function finished() { echo ; } ; # use this when testing or montaging to keep exported (tmp) .melt file; uncomment the below to remove the tmp file
#~ function finished() { rm /tmp/"$TMLTFILE"; echo "fin1 $0" ; } ; trap finished SIGINT ;
echo 'Remember `pulseaudio --start` to hear audio with `melt`!'
pulseaudio --check
if [ $? -ne 0 ]; then
pulseaudio --start
fi
DIRNAME=$(readlink -f $(dirname $0))
PROFILE="square_ntsc"
echo "
# the profile doesn't work from here;
# still has to be specified on command line
# but including it here so the path is saved for testing
#~ -profile
#~ ${PROFILE}
-video-track
# can avoid pixmap: here, but that s the producer;
# qimage: also works
# NB it is NOT '-out 1645'; but 'out=1645'!!
/media/myimg/%05d.bmp
in=0
out=1645
#~ length=1645
#~ loop=0
#~ eof=stop
-audio-track
/media/mysnd/snd.wav
in=0
out=1645
#~ loop=0
#~ eof=stop
#-consumer xml # doesn't work here
" | sed -e 's/#.*$//' -e 's/^[[:space:]]*//' -e '/^[[:space:]]*$/d' -e 's/[[:blank:]]*$//' > ${TMLTFILE}
# the sed: remove comments; remove indents; remove empty lines; remove spaces at end of line
# eof: one of: stop, loop, continue or pause (eof=stop)
# to loop, use `melt eof=loop ...` (but make sure first,
# that the edit as a whole stops - use xml to check!)
# due to caching issues, preview pieces (up to ~300 frames) like this:
melt eof=loop -profile ${PROFILE} ${TMLTFILE} in=200 out=400
# must have profile here, for checking w/ -consumer xml (else segfault)
# this command may add additional producers to the xml!:
## melt -profile ${PROFILE} ${TMLTFILE} -consumer xml
# use this to generate xml if needed:
#melt -profile ${PROFILE} $(cat ${TMLTFILE} | tr '\n' ' ') -consumer xml
# if exited normally, cleanup:
finished
답변4
시간이 좀 지났지만 제목 질문에 대해서는 저에게 맞는 방식으로 답변해 보도록 하겠습니다.
이는 관련이 있습니다:BASH 프로세스 교체가 일부 명령에서 작동하지 않는 이유는 무엇입니까?
그래서 제가 해결하려는 구체적인 문제는 다음과 같습니다.
- 이미지 변환기가 있습니다.
- [임의의 형식 삽입]에서 BMP/PNM/TGA와 같은 간단한 형식으로 변환합니다.
- JPEG로 변환하고 싶기 때문에 ImageMagick과 연결해야 합니다
convert
. - 임시 파일을 사용하고 싶지 않습니다.
따라서 불행하게도 이 도구는 출력 파일 이름의 확장자에서 출력 형식을 파생시키기 때문에 stdout/fds/pipes로 출력하는 것을 좋아하지 않습니다. 그럼 어떻게 속일 수 있을까?
적절한 확장자를 가진 심볼릭 링크를 생성 /dev/fd/N
하고 "임시 파일"로 사용하십시오.
예:
ln -s /dev/fd/4 temp.pnm
[TOOL] -i [INPUTFILE] -o temp.pnm 4>&1 | convert - [OUTPUT.JPG]