Sử dụng thay thế quy trình để lừa các chương trình mong đợi các tệp, với các phần mở rộng cụ thể làm đối số?


7

Đây là trường hợp sử dụng của tôi: tiện ích dòng lệnh meltcó thể chấp nhận tên tệp, với phần mở rộng .melttrên dòng lệnh và mở nó; như một ví dụ, đây là một test_p.melttập tin thích hợp :

colour:blue
out=24

colour:red
out=48

... mở ra và chơi với melt test_p.melt.

Bây giờ, điều là .meltcác tệp không hỗ trợ các bình luận, điều mà tôi muốn họ đã làm (bạn sẽ nhận được thông báo lỗi cho bất kỳ dòng nào có chứa một đối số không thể sửa chữa, bao gồm cả những người có, giả sử, a #). Vì vậy, đây là một test_c.melttập tin nhận xét :

# master comment here

colour:blue  # this is blue!
out=24

colour:red
out=48

Mở cái này melttrực tiếp cho:

$ melt test_c.melt
Failed to load "# master comment here"
...

... và không có màn hình màu xanh hiển thị.

Vì vậy, tôi nghĩ - tốt, dù sao tôi cũng có thể đưa ra nhận xét , sau đó sử dụng thay thế quy trình Bash để lọc tệp sedvà chỉ cần cung cấp cho meltứng dụng. Đầu tiên, thử một thử nghiệm cat, thành công:

$ cat <(sed 's/#.*$//' test_c.melt)



colour:blue  
out=24

colour:red
out=48

... Có vẻ tốt; nhưng , nếu tôi thử điều đó với melt, nó sẽ thấy qua mánh khóe của tôi:

$ melt <(sed 's/#.*$//' test_c.melt)
Failed to load "/dev/fd/62"
Failed to load "/dev/fd/62"

Về cơ bản, tan có tên tệp của ống Bash được cung cấp để thay thế quy trình - nhưng thật không may, cái meltmà nó xử lý argv[i]trực tiếp; và trong trường hợp của một tập tin, nó cần phải xem một .meltphần mở rộng trong tên tệp; nếu không - quá trình thất bại.

Vì vậy, câu hỏi của tôi là: làm thế nào tôi có thể sử dụng thay thế quá trình - vì vậy tên tệp của đường ống có phần mở rộng cụ thể, trong trường hợp này .melt? Về cơ bản, là kết quả của sự thay thế, tôi muốn có một tên tệp ống /dev/fd/62.meltmà tôi nghĩ sẽ vượt qua.

NB: tất nhiên, tôi luôn có thể làm:

sed 's/#.*$//' test_c.melt > test_c_temp.melt
melt test_c_temp.melt

... nhưng trước tiên, có hai lệnh ở đây - và tôi muốn một đường ống một lớp; và đối với một vấn đề khác, nó mở ra một vấn đề khác của tôi khi nghĩ về việc xóa các tệp tạm thời sau đó, điều mà tôi không thích.

Điều này có thể với sự thay thế quá trình Bash - hoặc bằng cách nào đó với các công cụ Linux tiêu chuẩn?


1
Hãy thửmelt < <(sed 's/#.*$//' test_c.melt)
Costas

Cảm ơn @Costas - đã thử nó, nhưng dường như meltkhông quan tâm đến các lệnh được truyền qua stdin, vì tôi nhận được: Usage: melt [options] [producer [name=value]* ]+và một loạt các tùy chọn chương trình. Chúc mừng!
sdaau

1
Tôi phải đọc man meltthay mặt bạn. " Nếu không có tệp nào được chỉ định, việc nén được áp dụng cho đầu vào tiêu chuẩn ". Vì vậy, sed 's/#.*$//' test_c.melt | melt > result.filecó thể làm việc.
Costas

Cảm ơn một lần nữa, @Costas - thật không may, điều đó cũng không hoạt động, ít nhất là không phải trên phiên bản của tôi melt(MLT tan 0.6.2; "đầu vào tiêu chuẩn" không được đề cập trong phiên bản này man melt), vì lệnh đó, một lần nữa tôi nhận được Usage: melt [options] [producer [name=value]* ]+và một bãi chứa. Chúc mừng!
sdaau

Tôi nghĩ bạn phải đọc man melttrên máy của bạn. Nếu bạn không thể tìm thấy bài trả lời trên pastebin.com và đăng liên kết ở đây.
Costas

Câu trả lời:


3

Một khả năng sẽ là trỏ meltđến một hệ thống tệp hiển thị các bản sao của tệp đã được sửa đổi. FUSE là một cách chung để xây dựng trình điều khiển hệ thống tập tin được thực hiện bởi một chương trình thông thường và không yêu cầu đặc quyền. Có rất nhiều hệ thống tập tin FUSE xung quanh , và rất có thể một trong số chúng có thể giúp bạn. Ý tưởng là cung cấp một điểm gắn kết trong đó việc đọc một .melttệp đọc tệp tin Real thực sự nhưng với các bình luận được lọc ra.

ScriptFS có vẻ đầy hứa hẹn (nhưng tôi chưa bao giờ sử dụng nó). Một cái gì đó như thế này sẽ hoạt động:

mkdir ~/uncommented-melt
scriptfs -p "$HOME/bin/uncomment-melt;&*.melt" ~/work ~/uncommented-melt

nơi ~/worklà gốc rễ của cây có chứa của bạn .melttập tin và ~/bin/uncomment-melt

#!/bin/sh
sed 's/#.*$//' "$1"

Sau đó, nếu bạn có một tập tin ~/work/test_c.meltvới ý kiến, bạn có thể chạy melt ~/uncommented-melt/test_c.melt.

Các hệ thống tập tin FUSE hữu ích tiềm năng khác:

  • Execfuse - cho phép bạn xây dựng trình điều khiển FUSE đơn giản với các tập lệnh shell
  • AVFS hoặc các hệ thống tệp FUSE khác giải nén các tệp trong suốt: xác định tước các bình luận là một quy tắc giải nén.

Rất cám ơn vì điều đó @Gilles - Tôi đã chấp nhận câu trả lời này, vì nó trả lời câu hỏi một cách khái quát. Thật không may, tôi có thể không hoàn toàn được scriptfslàm việc - đây là một bản ghi lệnh tôi đã lưu vào thời điểm đó (AFAICR, stackexchange bị rơi ngày hôm đó :)) gist.github.com/anonymous/e9ee5e8c53d1b4c3c736 - vì vậy tôi đã kết thúc bằng một bashcách tiếp cận kịch bản mà tôi được đăng phía dưới. Chúc mừng!
sdaau 23/2/2015

2

Với zshshell, bạn có thể sử dụng =(...)hình thức thay thế quy trình (sử dụng tệp tạm thời thay vì /dev/fd/xtệp và đường ống) mà bạn có thể chỉ định hậu tố:

(TMPSUFFIX=.melt; melt =(sed 's/#.*$//' test_c.melt))

Xem info zsh TMPSUFFIX(giả sử các infotrang được cài đặt, bạn có thể cần cài đặt một zsh-docgói) để biết chi tiết.


1

Ok, hóa ra trong trường hợp cụ thể của tôi, các loại kịch bản tan chảy này sẽ được hiểu một cách nghiêm ngặt như các đối số dòng lệnh; vì vậy chỉ có một cái sedtrong OP không hoàn toàn cắt nó (cộng với, có những thứ khác như hồ sơ có thể được đặt). Vì vậy, đây là những gì tôi đã làm - có thể đóng vai trò là nguồn cảm hứng trong các trường hợp khác mà tiêu đề của OP sẽ đề cập.

Cuối cùng tôi đã quyết định sử dụng điều này: tạo một test.shmelttệp, thực sự là một bashtập lệnh chứa meltmã tập lệnh nhận xét của tôi ; làm cho tập tin này được thực thi chmod +x test.shmelt; Sau khi chỉnh sửa tập lệnh, hãy chạy nó dưới dạng ./test.shmelt.

Khi chạy, nó sẽ tạo một test.melttệp "đã dọn sạch" /tmpmeltthay vào đó gọi vào tệp này. Vì meltthường tiếp tục chạy trong thiết bị đầu cuối sau khi kết thúc chương trình, với một bẫy trên SIGINT, tệp tạm thời này có thể được dọn sạch khi nhấn Ctrl-C (nhưng không phải).

Theo cách đó, tôi vẫn có ý kiến; có thể chỉnh sửa nhanh chóng trong tệp nguồn và chạy tan chảy và xem kết quả; và có một tập tin "dọn dẹp" các bình luận quá, mà tôi có thể sử dụng sau này.

Đây là mã của 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

1

Đã được một lúc, nhưng tôi sẽ cố gắng trả lời câu hỏi tiêu đề theo cách có ích cho tôi.

Điều này có liên quan: Tại sao quá trình thay thế BASH không hoạt động với một số lệnh?

Vì vậy, vấn đề cụ thể tôi đã cố gắng giải quyết là:

  1. Tôi có một công cụ chuyển đổi hình ảnh;
  2. nó chuyển đổi từ [chèn định dạng ngẫu nhiên] sang các định dạng đơn giản như BMP / PNM / TGA;
  3. Tôi muốn chuyển đổi sang JPEG, vì vậy cần phải xâu chuỗi nó bằng ImageMagick convert;
  4. Tôi không muốn sử dụng các tập tin tạm thời.

Vì vậy, thật không may, công cụ không muốn xuất ra thiết bị xuất chuẩn / fds / ống vì nó lấy định dạng đầu ra từ phần mở rộng của tên tệp đầu ra. Vậy làm thế nào để lừa nó?

Tạo một liên kết mềm với phần mở rộng thích hợp /dev/fd/Nvà sử dụng đó làm "tệp tạm thời".

Thí dụ:

ln -s /dev/fd/4 temp.pnm
[TOOL] -i [INPUTFILE] -o temp.pnm 4>&1 | convert - [OUTPUT.JPG]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.