@@ -12,22 +12,31 @@ import (
12
12
"golang.org/x/crypto/ssh/terminal"
13
13
)
14
14
15
+ const (
16
+ localDevice = "local"
17
+ networkDevice = "network"
18
+ fuseDevice = "fuse"
19
+ specialDevice = "special"
20
+ loopsDevice = "loops"
21
+ bindsMount = "binds"
22
+ )
23
+
15
24
var (
16
25
Version = ""
17
26
CommitSHA = ""
18
27
19
28
term = termenv .EnvColorProfile ()
20
29
theme Theme
21
30
31
+ allowedValues = strings .Join ([]string {localDevice , networkDevice , fuseDevice , specialDevice , loopsDevice , bindsMount }, ", " )
32
+
22
33
all = flag .Bool ("all" , false , "include pseudo, duplicate, inaccessible file systems" )
23
- hideLocal = flag .Bool ("hide-local" , false , "hide local devices" )
24
- hideNetwork = flag .Bool ("hide-network" , false , "hide network devices" )
25
- hideFuse = flag .Bool ("hide-fuse" , false , "hide fuse devices" )
26
- hideSpecial = flag .Bool ("hide-special" , false , "hide special devices" )
27
- hideLoops = flag .Bool ("hide-loops" , true , "hide loop devices" )
28
- hideBinds = flag .Bool ("hide-binds" , true , "hide bind mounts" )
34
+ hideDevices = flag .String ("hide" , "" , "hide specific devices, separated with commas:\n " + allowedValues )
29
35
hideFs = flag .String ("hide-fs" , "" , "hide specific filesystems, separated with commas" )
30
36
37
+ onlyDevices = flag .String ("only" , "" , "show only specific devices, separated with commas:\n " + allowedValues )
38
+ onlyFs = flag .String ("only-fs" , "" , "only specific filesystems, separated with commas" )
39
+
31
40
output = flag .String ("output" , "" , "output fields: " + strings .Join (columnIDs (), ", " ))
32
41
sortBy = flag .String ("sort" , "mountpoint" , "sort output by: " + strings .Join (columnIDs (), ", " ))
33
42
width = flag .Uint ("width" , 0 , "max output width" )
@@ -42,64 +51,93 @@ var (
42
51
43
52
// renderTables renders all tables.
44
53
func renderTables (m []Mount , columns []int , sortCol int , style table.Style ) {
45
- var local , network , fuse , special []Mount
46
- hideFsMap := parseHideFs (* hideFs )
54
+ deviceMounts := make (map [string ][]Mount )
55
+ hideDevicesMap := parseCommaSeparatedValues (* hideDevices )
56
+ onlyDevicesMap := parseCommaSeparatedValues (* onlyDevices )
57
+ hasOnlyDevices := len (onlyDevicesMap ) != 0
58
+ hideFsMap := parseCommaSeparatedValues (* hideFs )
59
+ onlyFsMap := parseCommaSeparatedValues (* onlyFs )
60
+
61
+ _ , hideLocal := hideDevicesMap [localDevice ]
62
+ _ , hideNetwork := hideDevicesMap [networkDevice ]
63
+ _ , hideFuse := hideDevicesMap [fuseDevice ]
64
+ _ , hideSpecial := hideDevicesMap [specialDevice ]
65
+ _ , hideLoops := hideDevicesMap [loopsDevice ]
66
+ _ , hideBinds := hideDevicesMap [bindsMount ]
67
+
68
+ _ , onlyLocal := onlyDevicesMap [localDevice ]
69
+ _ , onlyNetwork := onlyDevicesMap [networkDevice ]
70
+ _ , onlyFuse := onlyDevicesMap [fuseDevice ]
71
+ _ , onlySpecial := onlyDevicesMap [specialDevice ]
72
+ _ , onlyLoops := onlyDevicesMap [loopsDevice ]
73
+ _ , onlyBinds := onlyDevicesMap [bindsMount ]
47
74
48
75
// sort/filter devices
49
76
for _ , v := range m {
50
- // skip hideFs
51
- if _ , ok := hideFsMap [v .Fstype ]; ok {
52
- continue
77
+ if len (onlyFsMap ) != 0 {
78
+ // skip not onlyFs
79
+ if _ , ok := onlyFsMap [strings .ToLower (v .Fstype )]; ! ok {
80
+ continue
81
+ }
82
+ } else {
83
+ // skip hideFs
84
+ if _ , ok := hideFsMap [strings .ToLower (v .Fstype )]; ok {
85
+ continue
86
+ }
53
87
}
54
88
// skip autofs
55
89
if v .Fstype == "autofs" {
56
90
continue
57
91
}
92
+
58
93
// skip bind-mounts
59
- if * hideBinds && ! * all && strings .Contains (v .Opts , "bind" ) {
60
- continue
94
+ if strings .Contains (v .Opts , "bind" ) {
95
+ if (hasOnlyDevices && ! onlyBinds ) || (hideBinds && ! * all ) {
96
+ continue
97
+ }
61
98
}
99
+
62
100
// skip loop devices
63
- if * hideLoops && ! * all && strings .HasPrefix (v .Device , "/dev/loop" ) {
64
- continue
101
+ if strings .HasPrefix (v .Device , "/dev/loop" ) {
102
+ if (hasOnlyDevices && ! onlyLoops ) || (hideLoops && ! * all ) {
103
+ continue
104
+ }
65
105
}
106
+
66
107
// skip special devices
67
108
if v .Blocks == 0 && ! * all {
68
109
continue
69
110
}
111
+
70
112
// skip zero size devices
71
113
if v .BlockSize == 0 && ! * all {
72
114
continue
73
115
}
74
116
75
- if isNetworkFs (v ) {
76
- network = append (network , v )
77
- continue
78
- }
79
- if isFuseFs (v ) {
80
- fuse = append (fuse , v )
81
- continue
82
- }
83
- if isSpecialFs (v ) {
84
- special = append (special , v )
85
- continue
86
- }
87
-
88
- local = append (local , v )
117
+ deviceType := deviceType (v )
118
+ deviceMounts [deviceType ] = append (deviceMounts [deviceType ], v )
89
119
}
90
120
91
121
// print tables
92
- if ! * hideLocal || * all {
93
- printTable ("local" , local , sortCol , columns , style )
94
- }
95
- if ! * hideNetwork || * all {
96
- printTable ("network" , network , sortCol , columns , style )
97
- }
98
- if ! * hideFuse || * all {
99
- printTable ("FUSE" , fuse , sortCol , columns , style )
100
- }
101
- if ! * hideSpecial || * all {
102
- printTable ("special" , special , sortCol , columns , style )
122
+ for deviceType , mounts := range deviceMounts {
123
+ shouldPrint := * all
124
+
125
+ if ! shouldPrint {
126
+ switch deviceType {
127
+ case localDevice :
128
+ shouldPrint = (hasOnlyDevices && onlyLocal ) || (! hasOnlyDevices && ! hideLocal )
129
+ case networkDevice :
130
+ shouldPrint = (hasOnlyDevices && onlyNetwork ) || (! hasOnlyDevices && ! hideNetwork )
131
+ case fuseDevice :
132
+ shouldPrint = (hasOnlyDevices && onlyFuse ) || (! hasOnlyDevices && ! hideFuse )
133
+ case specialDevice :
134
+ shouldPrint = (hasOnlyDevices && onlySpecial ) || (! hasOnlyDevices && ! hideSpecial )
135
+ }
136
+ }
137
+
138
+ if shouldPrint {
139
+ printTable (deviceType , mounts , sortCol , columns , style )
140
+ }
103
141
}
104
142
}
105
143
@@ -144,21 +182,23 @@ func parseStyle(styleOpt string) (table.Style, error) {
144
182
case "ascii" :
145
183
return table .StyleDefault , nil
146
184
default :
147
- return table.Style {}, fmt .Errorf ("Unknown style option: %s" , styleOpt )
185
+ return table.Style {}, fmt .Errorf ("unknown style option: %s" , styleOpt )
148
186
}
149
187
}
150
188
151
- // parseHideFs parses the supplied hide-fs flag into a map of fs types which should be skipped .
152
- func parseHideFs ( hideFs string ) map [string ]struct {} {
153
- hideMap := make (map [string ]struct {})
154
- for _ , fs := range strings .Split (hideFs , "," ) {
155
- fs = strings .TrimSpace (fs )
156
- if len (fs ) == 0 {
189
+ // parseCommaSeparatedValues parses comma separated string into a map.
190
+ func parseCommaSeparatedValues ( values string ) map [string ]struct {} {
191
+ items := make (map [string ]struct {})
192
+ for _ , value := range strings .Split (values , "," ) {
193
+ value = strings .TrimSpace (value )
194
+ if len (value ) == 0 {
157
195
continue
158
196
}
159
- hideMap [fs ] = struct {}{}
197
+ value = strings .ToLower (value )
198
+
199
+ items [value ] = struct {}{}
160
200
}
161
- return hideMap
201
+ return items
162
202
}
163
203
164
204
func main () {
0 commit comments