Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Equal strings don't match!

by pl (Initiate)
on Jul 30, 2008 at 18:07 UTC ( [id://701199]=perlquestion: print w/replies, xml ) Need Help??

pl has asked for the wisdom of the Perl Monks concerning the following question:


Can you tell me why the condition if( $elem eq "/usr/sbin/sshd" does not match? @cmd gets an element with the string "/usr/sbin/sshd", retrieved from the "cmdline" file (that is in /proc, in the directory of the process)...

opendir(PROC,"/proc"); @PROC = readdir PROC; closedir(PROC); @PID = grep /[0-9]/, @PROC; chomp(@PID); for($k=0;$k<@PID;$k++){ open(CMDLINE,"<","/proc/$PID[$k]/cmdline") ; ($CMDLINE) = <CMDLINE>; push(@CMD,$CMDLINE); close(CMDLINE); } foreach $elem (@CMD){ if( $elem eq "/usr/sbin/sshd" ){ # <<-- print "found\n"; } else{ print "not found\n"; } } exit 1;



Replies are listed 'Best First'.
Re: Equal strings don't match!
by kyle (Abbot) on Jul 30, 2008 at 18:28 UTC

    On my system, stuff read from /proc/*/cmdline comes complete with a trailing null character (chr 0) and also nulls separating the command from its arguments. I might rewrite your code this way:

    use strict; use warnings; opendir my $proc_dh, '/proc' or die "Can't opendir '/proc': $!"; my @every_pid = grep /\d/, readdir $proc_dh; closedir $proc_dh; chomp @every_pid; my @every_cmd; foreach my $pid ( @every_pid ) { open my $cmdline_fh, '<', "/proc/$pid/cmdline" or die "Can't open '/proc/$pid/cmdline': $!\n"; my ($cmd) = split /\0/, scalar <$cmdline_fh>; push @every_cmd, $cmd if defined $cmd; close $cmdline_fh; } if ( grep { '/usr/sbin/sshd' eq $_ } @every_cmd ) { print "found\n"; } else { print "not found\n"; }

    Notice that,

    I would point out also that you may be able to say "ps -C sshd" at your command prompt and find out what you want.

      Thanks,but this is just a small part of my program,I need to get the values exactly like they are or I will need to change other parts of the program. I need to know why they don't match, because they look the same! Even with chomp the code doesn't work(I have already checked if the cmdline has newlines, but it doesn't)! You think that if I remove the null character(\0) in all elements of @CMD, it will work?

        The null character does seem to be the only difference between what you have in @CMD and the literal string. Have you tried removing it? You could remove nulls from everything in that array this way:

        tr/\0//d for @CMD;

        That means, however, that a command line with several arguments (e.g., "echo one two") will have those arguments all stuck together (e.g., "echoonetwo") instead of separated with nulls.

        Without knowing what you're really trying to do, it's hard to give good advice. See XY Problem.

        Problem resolved! It was the null character(\0)...I used: $/ = "\0"; chomp(@CMD); Cheers, fl.
Re: Equal strings don't match!
by CountZero (Bishop) on Jul 30, 2008 at 18:12 UTC
    The usual answer is that they do not match because they are different. Issues of different character sets, "hidden" spaces at the start or the end or EOL characters may mess up your test. Do a print "**$elem**\n"; before the test so you can see what you are comparing.


    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I agree that they are likely to be different, but simply printing them with a delimiter will not show all possible differences.

      This is what I use instead:

      use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper($str1, $str2);
      Also, I think the cmdline file has oddball characters in it sometimes...

      $elem =~ s/([^[:print]])/'\x'.unpack("H*", $1)/eg; might, therefore be revealing as well.


Re: Equal strings don't match!
by toolic (Bishop) on Jul 30, 2008 at 18:15 UTC
    Maybe $elem has a trailing newline character. Did you try to chomp @CMD?

    Please use "code" tags instead of "pre" tags, and only use them around your code snippets. Your posting renders poorly. Re-read Writeup Formatting Tips.

Re: Equal strings don't match!
by olus (Curate) on Jul 30, 2008 at 18:13 UTC

    Maybe $elem has an extra \n that needs to be chomped?

Re: Equal strings don't match!
by MidLifeXis (Monsignor) on Jul 30, 2008 at 18:13 UTC

    I don't have linux available to me right now, but are there newlines at the end of the command lines you are reading? Try the chomp command.


      No,there aren't newlines at "cmdline" file!No need to "chomp"...
Re: Equal strings don't match!
by Fletch (Bishop) on Jul 30, 2008 at 18:15 UTC

    perldoc chomp

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://701199]
Approved by superfrink
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-07-18 03:07 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.