www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to list all process directories under /proc/

reply Ky-Anh Huynh <saigon example.net> writes:
Hi,

I want to list all processes by scanning /proc/. The following 
code doesn't work

[code]
   foreach (string fstatm; dirEntries("/proc/", "[0-9]*", 
SpanMode.shallow)) {
     writefln("pid %s", fstatm);
   }
[/code]

as it only list a few entries before exiting

[code]
pid /proc/9
pid /proc/935
pid /proc/9146
pid /proc/9149
pid /proc/9150
pid /proc/9151
pid /proc/9756
pid /proc/9759
pid /proc/9760
pid /proc/9761
[/code]

I don't want to use `SpanMode.depth` or `SpanMode.breadth` 
because it will scan so deeply and there would be a permission 
problem.

Any ideas?

Thanks a lot
Sep 17
next sibling parent reply Ky-Anh Huynh <saigon example.net> writes:
On Sunday, 17 September 2017 at 08:15:58 UTC, Ky-Anh Huynh wrote:
 Hi,

 I want to list all processes by scanning /proc/. The following 
 code doesn't work

 [code]
   foreach (string fstatm; dirEntries("/proc/", "[0-9]*", 
 SpanMode.shallow)) {
     writefln("pid %s", fstatm);
   }
 [/code]

 as it only list a few entries before exiting

 [code]
 pid /proc/9
 pid /proc/935
 pid /proc/9146
 pid /proc/9149
 pid /proc/9150
 pid /proc/9151
 pid /proc/9756
 pid /proc/9759
 pid /proc/9760
 pid /proc/9761
 [/code]

 I don't want to use `SpanMode.depth` or `SpanMode.breadth` 
 because it will scan so deeply and there would be a permission 
 problem.

 Any ideas?

 Thanks a lot
My bad. Range doesn't support. The correct pattern is [code] foreach (string fstatm; dirEntries("/proc/", "[0123456789]*", SpanMode.shallow)) { writefln("pid %s", fstatm); } [/code] Is there a way to make this simpler?
Sep 17
parent reply Ky-Anh Huynh <saigon example.net> writes:
On Sunday, 17 September 2017 at 08:32:24 UTC, Ky-Anh Huynh wrote:
 My bad. Range doesn't support. The correct pattern is

 [code]
   foreach (string fstatm; dirEntries("/proc/", "[0123456789]*", 
 SpanMode.shallow)) {
     writefln("pid %s", fstatm);
   }
 [/code]

 Is there a way to make this simpler?
The official documentation here https://dlang.org/phobos/std_path.html#.globMatch refers to the wiki page https://en.wikipedia.org/wiki/Glob_%28programming%29 . However I think the popular glob rules (man 7 glob) are not supported.
Sep 17
parent reply Matt Jones <matthew.brennan.jones gmail.com> writes:
On Sunday, 17 September 2017 at 08:37:33 UTC, Ky-Anh Huynh wrote:

 The official documentation here 
 https://dlang.org/phobos/std_path.html#.globMatch refers to the 
 wiki page https://en.wikipedia.org/wiki/Glob_%28programming%29 
 . However I think the popular glob rules (man 7 glob) are not 
 supported.
The problem with matching "[0123456789]*" is that it will match files like "1blah" and "8stuff". It looks like glob patterns are not robust enough to handle match patterns you want. A regex would probably be enough. Something like this works: string[] getProcNumbers() { import std.file : dirEntries, SpanMode; import std.path : baseName; import std.regex : regex, match; import std.algorithm : map, filter; import std.array : array; auto r = regex(`^/proc/[0-9]*$`); string[] entries = dirEntries("/proc/", SpanMode.shallow) .map!(n => n.name) .filter!(n => match(n, r)) .array(); return entries; } int main() { import std.stdio : stdout; foreach (entry ; getProcNumbers()) { stdout.writefln("%s", entry); } return 0; }
Sep 18
parent reply Ky-Anh Huynh <saigon example.net> writes:
On Tuesday, 19 September 2017 at 06:35:18 UTC, Matt Jones wrote:
 On Sunday, 17 September 2017 at 08:37:33 UTC, Ky-Anh Huynh 
 wrote:

 [...]
The problem with matching "[0123456789]*" is that it will match files like "1blah" and "8stuff". It looks like glob patterns are not robust enough to handle match patterns you want. A regex would probably be enough. Something like this works: [...]
I understand. Thanks a lot. Btw, is that a bit weird that range is not supported in glob pattern :) Is there a design reason for this?
Sep 19
parent reply Matt Jones <matthew.brennan.jones gmail.com> writes:
On Tuesday, 19 September 2017 at 13:32:29 UTC, Ky-Anh Huynh wrote:

 Btw, is that a bit weird that range is not supported in glob 
 pattern :) Is there a design reason for this?
That is strange. But then again, every glob library I've seen works a little bit differently.
Sep 19
parent Ky-Anh Huynh <saigon example.net> writes:
On Tuesday, 19 September 2017 at 18:32:06 UTC, Matt Jones wrote:
 On Tuesday, 19 September 2017 at 13:32:29 UTC, Ky-Anh Huynh 
 wrote:

 Btw, is that a bit weird that range is not supported in glob 
 pattern :) Is there a design reason for this?
That is strange. But then again, every glob library I've seen works a little bit differently.
I see. Maybe I'm using Linux and Ruby too much. Missing character range doesn't really hurt, but the feature should be documented. Should we improve the documentation? To be fair, the syntax specification is clear after I read it twice, but the link to Wiki page is confusing, because Wiki page mentions the popular (FIXME) implementation with character range.
Sep 19
prev sibling parent angel <andrey.gelman gmail.com> writes:
On Sunday, 17 September 2017 at 08:15:58 UTC, Ky-Anh Huynh wrote:
 Hi,

 I want to list all processes by scanning /proc/. The following 
 code doesn't work

 [code]
   foreach (string fstatm; dirEntries("/proc/", "[0-9]*", 
 SpanMode.shallow)) {
     writefln("pid %s", fstatm);
   }
 [/code]

 as it only list a few entries before exiting

 [code]
 pid /proc/9
 pid /proc/935
 pid /proc/9146
 pid /proc/9149
 pid /proc/9150
 pid /proc/9151
 pid /proc/9756
 pid /proc/9759
 pid /proc/9760
 pid /proc/9761
 [/code]

 I don't want to use `SpanMode.depth` or `SpanMode.breadth` 
 because it will scan so deeply and there would be a permission 
 problem.

 Any ideas?

 Thanks a lot
Are you familiar with libprocps ? Maybe you had better make use of this library, or, at least, peek into its code, for reference.
Sep 22