Bash

文件在不同的作業系統上提供不同的 Mime 類型

  • July 20, 2021

所以我有一個 bash 腳本,它部分執行以下操作:

file -b --mime-type "$1"

然後我有邏輯來檢查它是否是預期的文件類型。

if [[ $type == "application/gzip" ]]; then
   <stuff>
   exit 0
fi

# basically the else
echo "File type $type not supported"

所以我在 Debian 系統上建構了這個腳本,所有的邏輯都很好。然而,當一位同事問他是否可以在他正在使用的某些系統(基於 CentOS)上使用它時,他不斷得到以下錯誤輸出:

File type application/x-gzip not supported

該腳本旨在可移植,因此使用 bash 和 file 等。我試圖在/usr/share/magicCentOS 系統上查看,它似乎是純文字。然而,在 Debian 上,它是二進制格式,並且更難與之互動。

所以我的理解是,通過呼叫---mime-type這將在每個作業系統上每次顯示相同的 mime 類型。我知道我可以將 if 添加application/x-gzip到 if 語句中,但是如果有辦法使輸出保持一致,我寧願將其作為一個選項。另外,如果我將來在這個腳本中添加其他部分,或者將它用作未來工作的模板,我希望有一種方法可以在作業系統之間獲得一致的輸出,這樣我就不必擔心很多邊緣案例。

如果有辦法獲得一致的答案,我可以更改為文件以外的其他內容。

提前致謝。

編輯#00

我最初將 IANA 視為參考,但後來意識到 IANA 無法辨識許多類型。這當然會讓事情變得更糟。

至於您對版本差異的建議,我認為這可能是根本原因,因為 Debian 系統在附近:

redacted@redacted ~$ file -v
file-5.35
magic file from /etc/magic:/usr/share/misc/magic

而 CentOS 系統位於:

redacted@redacted ~$ file -v
file-5.11
magic file from /etc/magic:/usr/share/misc/magic

至於來自 strace 的測試,它確實出現(以及上面兩種環境的備份)正在讀取 /etc/magic 中的文件,而在 CentOS 的情況下,它是純文字的。strace 看起來像:

strace -e trace=stat,open,openat file -i bob.txt
open("/usr/lib64/tls/x86_64/libmagic.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/tls/x86_64", 0x7fff0427d1d0) = -1 ENOENT (No such file or directory)
open("/usr/lib64/tls/libmagic.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/tls", {st_mode=S_IFDIR|0555, st_size=4096, ...}) = 0
open("/usr/lib64/x86_64/libmagic.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/x86_64", 0x7fff0427d1d0) = -1 ENOENT (No such file or directory)
open("/usr/lib64/libmagic.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib64/tls/libz.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib64/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
stat("/root/.magic.mgc", 0x7fff0427e750) = -1 ENOENT (No such file or directory)
stat("/root/.magic", 0x7fff0427e750)    = -1 ENOENT (No such file or directory)
stat("/etc/sysconfig/64bit_strstr_via_64bit_strstr_sse2_unaligned", 0x7fff0427dcb0) = -1 ENOENT (No such file or directory)
open("/etc/magic.mgc", O_RDONLY)        = -1 ENOENT (No such file or directory)
stat("/etc/magic", {st_mode=S_IFREG|0644, st_size=111, ...}) = 0
open("/etc/magic", O_RDONLY)            = 3
open("/usr/share/misc/magic.mgc", O_RDONLY) = 3
open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
stat("bob.txt", {st_mode=S_IFREG|0644, st_size=19, ...}) = 0
open("bob.txt", O_RDONLY)               = 3
bob.txt: text/troff; charset=us-ascii
+++ exited with 0 +++

不要介意 troff 和 .txt 不匹配,這是故意的。TROFF 被選中,所以它不僅僅是純文字……

我會看看我的同事是否可以在 CentOS 盒子上更新文件的版本,看看結果是否更好。

編輯#01

因此,查看另一個工具 xdg-mime,我發現在該程序中(至少),x-gzip 和 gzip 之間似乎沒有功能差異。

xdg-mime 類型的原始碼,ll。 2427-35

它似乎被認為是該程序中的別名(我正在研究是否會有獨立的魔法儲存來解決這個問題)。因此,魔術文件中的任何一種變體似乎都很常見。

IANA 已於application/gzip2012 年定義。

但即對於 HTTP 有這個註釋:

$$ … $$或與以前的 HTTP 實現兼容,應用程序應該考慮 “x-gzip” 和 “x-compress” 分別等同於 “gzip” 和 “compress”。

但那是針對 HTTP/1.1 的,而且相當(非常)舊——而且是一種不同的遊戲,這完全取決於它的用途。

gzip 本身是從 90 年代初開始的,在那個時候,也有人說x-可以用於未註冊的子類型。

一般來說,兩者都已經被使用。如果可以選擇,我會使用非x-變體。但是由於野獸的性質,像這樣的事情100%的*一致性是非常困難的。*就像file隨著時代的變化而變化一樣,其他做同樣事情的工具也隨著時代的變化而變化。

至於標準等,RFC 6838(2013 年 1 月) 強烈反對使用x-類型。


如果看一下file命令本身,就會發現它在 2019 年x-gzip被替換為(從外觀上看)。gzip

請注意,還有一個帶有 x-gzip的 BGZF(Blocked gzip) 。這是*“更”*可以理解的,因為它是 gzip 的變體,儘管與上面提到的 RFC 相衝突。再說一遍,這些事情需要很長時間才能到位。它用於,誰知道,有多少應用程序等。


確保它一致的唯一方法是確保跨系統使用相同的數據庫。

file使用魔術模式文件 ,當然可以將其與腳本一起分發,*magic.mgc*並說應該將其放入$HOME/.magic或類似文件中-或使用-m腳本中的選項(使用此/這些魔術文件)。如果使用不同版本的人可能會遇到問題file- 但不確定是哪個版本等。

魔術文件以文本形式編寫,然後編譯成 mgc。

file -C -m my-magic-file

可以將其用作純文字。也許 CentOS 系統上發生了什麼?Astrace應該揭示發生了什麼,例如

strace -e trace=stat,open,openat file -i foo.ext

抱歉,如果這變得非常不一致並且到處都是。

引用自:https://unix.stackexchange.com/questions/659075