ps_f 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README +30 -0
  2. data/bin/ps_f +101 -0
  3. metadata +66 -0
data/README ADDED
@@ -0,0 +1,30 @@
1
+ = ps_f
2
+
3
+ == Description
4
+
5
+ ps_f emulates 'ps awxuf' on Mac OS X.
6
+
7
+ == Source Code
8
+
9
+ https://bitbucket.org/winebarrel/ps_f
10
+
11
+ == Install
12
+
13
+ gem install ps_f
14
+
15
+ == Example
16
+
17
+ shell> ps_f
18
+ USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
19
+ root 1 0.0 0.0 2512260 2160 ?? Ss 9:05AM 0:09.81 /sbin/launchd
20
+ sugawara 260 0.0 0.1 2563928 13648 ?? Ss 9:05AM 0:01.49 \_ com.apple.dock.extra
21
+ sugawara 231 0.0 0.0 2511704 1756 ?? Ss 9:05AM 0:04.48 \_ /sbin/launchd
22
+ sugawara 718 1.6 0.8 3793428 131332 ?? S 9:07AM 2:37.60 | \_ /Applications/iTerm.app/Contents/MacOS/
23
+ root 3453 0.0 0.0 2479984 2288 s001 Ss 9:50AM 0:00.02 | | \_ login -fp sugawara
24
+ sugawara 3454 0.0 0.0 2435492 2104 s001 S+ 9:50AM 0:00.04 | | | \_ -bash
25
+ root 10710 0.0 0.0 2490224 2328 s003 Ss 12:11PM 0:00.01 | | \_ login -fp sugawara
26
+ sugawara 672 0.3 1.4 1465496 231208 ?? S 9:07AM 7:19.22 | \_ /Applications/Google Chrome.app/Content
27
+ sugawara 18426 2.9 0.3 908880 57228 ?? S 2:40PM 0:16.89 | | \_ /Applications/Google Chrome.app/Con
28
+ sugawara 7838 0.0 0.3 908424 54156 ?? S 11:18AM 0:02.44 | | \_ /Applications/Google Chrome.app/Con
29
+ sugawara 4054 0.0 0.4 915828 71916 ?? S 10:02AM 0:05.18 | | \_ /Applications/Google Chrome.app/Con
30
+ ...
data/bin/ps_f ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+ out = `ps awxu -o ppid,command`
3
+ exit 1 unless $?.success?
4
+
5
+ lines = out.to_a.map {|i| i.strip }
6
+
7
+ header_line = lines.shift
8
+ headers_border = (header_line =~ /PPID\s+COMMAND\Z/)
9
+
10
+ headers = header_line.split(/\s+/).values_at(0...-2)
11
+ additional_headers = header_line.split(/\s+/).values_at(-2..-1)
12
+
13
+ rows = {}
14
+ tree = []
15
+
16
+ lines.each do |line|
17
+ line_head = line[0, headers_border].strip.split(/\s+/, headers.length)
18
+ pid = line_head[headers.index('PID')].to_i
19
+
20
+ line_head.each_with_index do |value, i|
21
+ rows[pid] ||= []
22
+ rows[pid] << value if 'COMMAND' != headers[i]
23
+ end
24
+
25
+ ppid, command = line[headers_border..-1].strip.split(/\s+/, additional_headers.length)
26
+ tree << [pid, ppid.to_i, command]
27
+ end
28
+
29
+ roots = tree.select {|pid, ppid, command| ppid.zero? }
30
+
31
+ def asm(tree, roots, pre_prefix, cmd_list)
32
+ h = {}
33
+
34
+ roots.each do |pid, ppid, command|
35
+ h[ppid] ||= []
36
+ h[ppid] << [pid, command]
37
+ end
38
+
39
+ h.each do |ppid, list|
40
+ list.each_with_index do |pid_cmd, i|
41
+ pid, command = pid_cmd
42
+
43
+ cmd_list << [pid, pre_prefix + ' \_ ' + command]
44
+
45
+ children = tree.select {|child| pid == child[1] }
46
+ child_pre_prefix = pre_prefix + ((i < list.length - 1) ? ' | ' : ' ')
47
+
48
+ asm(tree, children, child_pre_prefix, cmd_list)
49
+ end
50
+ end
51
+ end
52
+
53
+ cmd_list = []
54
+ asm(tree, roots, '', cmd_list)
55
+
56
+ tree_rows = cmd_list.map do |pid, command|
57
+ row = rows[pid]
58
+ row + [command[4..-1]]
59
+ end
60
+
61
+ header_row = headers.select {|i| i != 'COMMAND' } + ['COMMAND']
62
+ tree_rows.unshift(header_row)
63
+
64
+ collen_list = []
65
+
66
+ tree_rows.each do |row|
67
+ row.each_with_index do |col, i|
68
+ len = collen_list[i] || 0
69
+ collen_list[i] = col.length if col.length > len
70
+ end
71
+ end
72
+
73
+ tree_lines = []
74
+
75
+ tree_rows.each do |row|
76
+ fmt_list = []
77
+
78
+ row.each_with_index do |value, i|
79
+ fmt_list << (/\A[.\d]+\Z/ =~ value ? '%*s' : '%-*s')
80
+ end
81
+
82
+ format = fmt_list.join(' ')
83
+ values = collen_list.zip(row).flatten
84
+
85
+ tree_lines << (format % values).sub(/\s+\Z/, '')
86
+ end
87
+
88
+ max_cols = 0
89
+
90
+ if $stdout.tty?
91
+ max_cols = `stty size cols 2> /dev/null`.strip.sub(/\A.*\s+/, '').first.to_i
92
+ end
93
+
94
+ if ARGV.any? {|i| /\A[a-z]+\Z/ =~ i and /w/ =~ i}
95
+ max_cols = 0
96
+ end
97
+
98
+ tree_lines.each do |line|
99
+ line = line[0, max_cols] unless max_cols.zero?
100
+ puts line
101
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ps_f
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - winebarrel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-12-28 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description:
22
+ email: sgwr_dts@yahoo.co.jp
23
+ executables:
24
+ - ps_f
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - README
31
+ - bin/ps_f
32
+ homepage: https://bitbucket.org/winebarrel/ps_f
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.24
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: ps_f emulates 'ps awxuf' on Mac OS X.
65
+ test_files: []
66
+