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 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。