dongyi7669 2016-08-15 22:19
浏览 39
已采纳

如何在纯Go语言的Linux上实现“ file -s <file>”?

Intent:
Does Go have the functionality (package or otherwise) to perform a special file stat on Linux akin to the command file -s <path>

Example:

[root@localhost ~]# file /proc/uptime
/proc/uptime: empty
[root@localhost ~]# file -s /proc/uptime
/proc/uptime: ASCII text

Use Case:
I have a fileglob of files in /proc/* that I need to very quickly detect if they are truly empty instead of appearing to be empty.

Using The os Package:

Code:

result,_ := os.Stat("/proc/uptime")
fmt.Println("Name:",result.Name()," Size:",result.Size()," Mode:",int(result.Mode()))
fmt.Printf("%q",result)

Result:

Name: uptime  Size: 0  Mode: 292
&{"uptime" '\x00' 'Ĥ' {%!q(int64=63606896088) %!q(int32=413685520) %!q(*time.Location=&{ [] [] 0 0 <nil>})} {'\x03' %!q(uint64=4026532071) '\x01' '脤' '\x00' '\x00' '\x00' '\x00' '\x00' 'Ѐ' '\x00' {%!q(int64=1471299288) %!q(int64=413685520)} {%!q(int64=1471299288) %!q(int64=413685520)} {%!q(int64=1471299288) %!q(int64=413685520)} ['\x00' '\x00' '\x00']}}

Obvious Workaround:
There is the obvious workaround of the following. But it's a little over the top to need to call in a bash shell in order to get file stats.

output,_ := exec.Command("bash","-c","file -s","/proc/uptime").Output()
//parse output etc...

EDIT/MY PRACTICAL USE CASE:
Quickly determining which files are zero size without needing to read each one of them first.

file -s /cgroup/memory/lsf/<cluster>/*/tasks | <clean up commands> | uniq -c
6 /cgroup/memory/lsf/<cluster>/<jobid>/tasks: ASCII text
805 /cgroup/memory/lsf/<cluster>/<jobid>/tasks: empty

So in this case, I know that only those 6 jobs are running and the rest (805) have terminated. Reading the file works like this:

# cat /cgroup/memory/lsf/<cluster>/<jobid>/tasks
#

or

# cat /cgroup/memory/lsf/<cluster>/<jobid>/tasks
12352
53455
...
  • 写回答

2条回答 默认 最新

  • dpge74512 2016-08-16 05:23
    关注

    I'm afraid you might be confusing matters here: file is special in precisely a way it "knows" a set of heuristics to carry out its tasks.

    To my knowledge, Go does not have anything like this in its standard library, and I've not came across a 3rd-party package implementing a file-like functionality (though I invite you to search by relevant keywords on http://godoc.org)

    On the other hand, Go provides full access to the syscall interface of the underlying OS so when it comes to querying the OS in a way file does it, there's nothing you could not do in plain Go.

    So I suggest you to just fetch the source code of file, learn what it does in its mode turned on by the "-s" command-line option and implement that in your Go code. We'll try to have you with specific problems doing that — should you have any.

    Update

    Looks like I've managed to grasp the OP is struggling with: a simple check:

    $ stat -c %s /proc/$$/status && wc -c < $_
    0
    849
    

    That is, the stat call on a file under /proc shows it has no contents but actually reading from that file returns that contents.

    OK, so the solution is simple: instead of doing a call to os.Stat() while traversing the subtree of the filesystem one should instead merely attempt to read a single byte from the file, like in:

    var buf [1]byte
    f, err := os.Open(fname)
    if err != nil {
        // do something, or maybe ignore.
        // A not existing file is OK to ignore
        // (the POSIX error code will be ENOENT)
        // because after the `path/filepath.Walk()` fetched an entry for
        // this file from its directory, the file might well have gone.
    }
    _, err = f.Read(buf[:])
    if err != nil {
        if err == io.EOF {
            // OK, we failed to read 1 byte, so the file is empty.
        }
        // Otherwise, deal with the error
    }
    f.Close()
    

    You might try to be more clever and first obtain the stat information (using a call to os.Stat()) to see if the file is a regular file—to not attempt reading from sockets etc.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 PointNet++的onnx模型只能使用一次
  • ¥20 西南科技大学数字信号处理
  • ¥15 有两个非常“自以为是”烦人的问题急期待大家解决!
  • ¥30 STM32 INMP441无法读取数据
  • ¥15 R语言绘制密度图,一个密度曲线内fill不同颜色如何实现
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧,别用大模型回答,大模型的答案没啥用
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。