From: zy on 7 Mar 2010 06:04 On Mar 7, 11:58 am, zy <zyc...(a)gmail.com> wrote: > I have written a perl script to do this task. > I think I can handle quotes correctly now, including those in > "pwd" ; ls > > but these still remains a problem: > var=cmd;$var > or > alias var='cmd' This script is structurally ill in my view, but works anyway, disregarding the problems. #!/usr/bin/perl # list_external.pl: List external programmes that are possibly executed by a given bash script. # zy....(a)gmail.com (zy) use strict; use Switch; use Set::Scalar; our $DP=0; my @list; my $word="", my $is_function=0, my $is_case=0; my $list=Set::Scalar->new; my $keywords=Set::Scalar->new( qw( case do done elif else esac fi for function if in select then until while time )); my $builtins=Set::Scalar->new( qw( alias bg bind break builtin cd command compgen complete continue declare dirs disown echo enable eval exec exit export fc fg getopts hash help history jobs kill let local logout popd printf pushd pwd read readonly return set shift shopt source suspend test times trap type typeset ulimit umask unalias unset wait) ); my $basics=Set::Scalar->new( qw( ) ); my $exclude=Set::Scalar->new; $exclude= $basics + $builtins + $keywords; my $functions=Set::Scalar->new; sysopen(FILE , $ARGV[0], "r" ) or open(FILE, "<&=STDIN"); sub save { if( $word eq ""){ $is_function=0;return; } my $ins= $is_function?$functions:$list; $ins->insert($word); # print '=====<<',$word,'>>====='; $word=""; $is_function=0; } sub parse { # print "\n"; # $DP++; # print "=<",$DP,"="; my $delimiter=@_[0], my $skip=@_[1], my $init=@_[2]; my $q1=0, my $q2=0, my $sl=0; my $dollar=0, my $comment=0, my $crop_word=1; my $c, my $cc=undef; while(defined($c=getc(FILE))) { # print "$c"; if ( $comment and $c ne "\n" ){next;} if(not defined($cc) and $c eq '(' and $init eq '$(') { parse(')',1); } if(defined($delimiter)) { if( $c eq $delimiter and $cc ne '\\' ){ # print " "; # print "=>",$DP,"="; # $DP--; # print "\n"; save(); return; } } if($sl == 1) { $sl=0; next; } # variables or cases $c =~ /[(]/ && do { if($word ne ""){$is_function=1;}}; $c =~ /[=]/ && do { $word=""; $crop_word=0}; $c =~ /[)]/ && do { if($is_case == 1) {$is_case=0;$crop_word=1;$word="";} }; $c !~ /[A-Za-z0-9_\-~.\/]/ && do { if ( $word eq "if" ) { $crop_word=1;$word=""; next; #while } if ( $word eq "." or $word eq "source" ) { $crop_word=1;$word=""; next; #while } if ( $word eq "function" ) { # print "FUNCTION"; $crop_word=1;$word="";$is_function=1; next; #while } if ( $word eq "case" ) { # print "CASE"; $crop_word=0;$word="";$is_case=5; next; #while } if ( $word eq "esac" ) { # print "ESAC"; $crop_word=0;$word="";$is_case=0; next; #while } # e.g. A command quoted with " and head of line; if ($word ne "" and not $is_case) { $crop_word=0;save(); } }; switch($c) { case '\\' { $sl=1;last; } case '#' { $comment=1;last; } case ' ' { # print ' '; $dollar=0; } case ';' { $is_case= $cc eq ';'? 1:0 ; if ( $word ne "" ){ save(); } if( not $q1 and not $q2 and not $is_case){ $crop_word=1; } last; } case "\n" { # print "\n"; $dollar=0; $comment=0; if($is_case != 0){$is_case=1;} if ( $word ne "" ){ save(); } if( not $q1 and not $q2){ $crop_word=1; } last; } case "'" { if($q2 != 1){ $q1= $q1?0:1; } last; } case '"' { if($q1!=1){ $q2= $q2?0:1; } last; } case '[' { if( not $q1 && not $q2 ){ parse(']',1); last; } } case '$' { $dollar=1; last; } case '(' { if($dollar == 1){ parse(')', 0, '$('); # print 'returned;$q2=',$q2,"\n"; last; } if( $cc eq '('){ parse(')',1,'((');parse(')',1); } } case '{' { if($dollar == 1){ parse('}',1); last; } } case '`' { parse('`'); } case /[|;]/ { if( $q1 || $q2 ){ last; } $crop_word=1; } case '&' { if( $q1 || $q2 || $cc ne '&' ){ last; } $crop_word=1; } case /[()\[\]\{\}]/ { last; } else{ if($dollar==1){$dollar=2} if(not $skip and not $dollar and not $comment){ # print $c; if($crop_word && $c =~ /[A-Za-z0-9_\-~.\/]/ ) {$word=$word . $c; } } } #switch } $cc=$c; #while } save(); } parse; print $list->difference($exclude+$functions), "\n"; close(FILE);
From: bsh on 10 Mar 2010 18:50 On Mar 6, 7:43 pm, zy <zyc...(a)gmail.com> wrote: > > My *guess* is that the OP wants to create a list of programs .... > Your guess is indeed right.... > Unfortunately, the problem of "CMD=pwd; $CMD" does exist.... There have been several toolsuites over the years addressing this issue, usually in the context of executable or script migration between Unix hosts. Unfortunately, all of them are either currently inaccessable or (probably) not pertainent to your environment -- are you programming on a Solaris host? The Solaris executable "scriptran", component of SLPT (Solaris-Linux Porting Tools), addressed your concern precisely. Others are "shanalyze" and "Linux-it". Too bad, but they are probably too complex and broad for what you are endeavoring to do. Previous discussions of mine can be found in previous posts: "convert solaris to linux" http://groups.google.com/group/comp.unix.shell/msg/99da9e2d6c2e79f6 "Converting from MKS Korn Shell to Linux" http://groups.google.com/group/comp.unix.shell/msg/51ed6773be861c72 However, the only solution which has not been discussed is the most obvious one! Use "truss" (Use "strace" on Linux), and "grep" for keywords (IIRC) "execve(" and (IIRC) "ENOENT" to find those external calls which are not resolved. The advantage of the above technique is that calls obfusticated by shell semantics, including variable substitution, will not be shrouded. =Brian
From: zy on 11 Mar 2010 00:07 On Mar 11, 7:50 am, bsh <brian_hi...(a)rocketmail.com> wrote: > Unfortunately, all of them are either currently > inaccessable or (probably) not pertainent to your > environment -- are you programming on a Solaris host? I write scripts on my Debian laptop, and upload it to another Debian. > However, the only solution which has not been > discussed is the most obvious one! Use "truss" > (Use "strace" on Linux), and "grep" for keywords > (IIRC) "execve(" and (IIRC) "ENOENT" to find > those external calls which are not resolved. The dynamic approaches are not very suitable to my situation. My scripts works over the network and act differently according to received data from some servers. It is hard to transverse through all the routes. And generally, some code is not meant to be executed at arbitary time. I would be very glad if there are some robust shell syntax analyzers available besides the interpreters, though they are not likely to be able to solve the issue of substituted commands.
From: bsh on 12 Mar 2010 15:18 On Mar 10, 9:07 pm, zy <zyc...(a)gmail.com> wrote: > On Mar 11, 7:50 am, bsh <brian_hi...(a)rocketmail.com> wrote: > > > Unfortunately, all of them are either currently > > inaccessable or (probably) not pertainent to your > > environment -- are you programming on a Solaris host? > > I write scripts on my Debian laptop, and upload it to another Debian. > > > However, the only solution which has not been > > discussed is the most obvious one! Use "truss" > > (Use "strace" on Linux), and "grep" for keywords > > (IIRC) "execve(" and (IIRC) "ENOENT" to find > > those external calls which are not resolved. > > The dynamic approaches are not very suitable to my situation. > My scripts works over the network and act differently according to > received data from some servers. It is hard to transverse through all > the routes. > And generally, some code is not meant to be executed at arbitary time. > > I would be very glad if there are some robust shell syntax analyzers > available besides the interpreters, though they are not likely to be > able to solve the issue of substituted commands. Hmmm. This is considerably tougher. Amusing, _I_ am that author of a robust shell syntax parser / analyzer, as I contritely make C.U.S. periodically aware, as it is stuck on a dead workstation. I can now only suggest downloading and experimenting with the bash debugger, bashdb, at: "bashdb.bash": bash(1) debugger http://sf.net/projects/bashdb/ http://bashdb.sf.net/ I have used the standalone ksh debugger script, precursor to bashdb, which in bash I also understand is built into version 3 and newer. Beyond the aforementioned longstanding project of a k/sh IDE including debugger suite and parser, I have no experience with this utility. I'm thinking that your script can be modified to "automagically" invoke the debugger, and trace data be written to a logfile, for your purposes. =Brian
From: Mark Hobley on 12 Mar 2010 18:08 zy <zyconf(a)gmail.com> wrote: > I would be very glad if there are some robust shell syntax analyzers > available besides the interpreters, though they are not likely to be > able to solve the issue of substituted commands. If you know perl and want to attempt this, it would be cool to add a -r switch to the checkbashisms tool to cause additional checks according to the traditional restricted rsh shell (which does not allow external commands to be executed). ftp://markhobley.yi.org/devtools/checkbashisms/ My email is down at this time, but I can receive update submissions via the comp.sources.unix newsgroup. Mark. -- Mark Hobley Linux User: #370818 http://markhobley.yi.org/
First
|
Prev
|
Pages: 1 2 3 4 Prev: Fast GUI pipemeter: gprog Next: scp selected files, create directory if needed |