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

I have written a shell function "pscnt" in .profile. But I could NOT call this shell fuction in my perl script using system, exec or ``.

Here is the code,

$running = `pscnt $inv_app_name $parameter`;
Could you please help me on this?

Janitored by holli - removed <pre>-tags

Replies are listed 'Best First'.
Re: Calling Shell funtion in Perl script
by mda2 (Hermit) on May 24, 2005 at 15:18 UTC
    To do it you need to exec your profile in shell data:
    perl -e 'system(". .bash_rc; test_shell")' __END__ TEST on shell function!!!
    initial dot equivales a source command

    .bash_rc

    test_shell() { echo "TEST on shell function!!!" }

    --
    Marco Antonio
    Rio-PM

      This pscnt function is to determine if any program name (and parameter) passed in is actually a running process. If so, returns count of running instances. I tried this code, but I get count as 2. my $running = `. ~/.profil > /dev/null; pscnt $app_name $parameter`; I am not sure if the code is correct. So, please help me to sort out this issue.

        This should work.

        In . ~/.profil > /dev/null, is the missing e a typo that appears in your real code too?

        Also the `` operator is calling /bin/sh, so if you are using a different shell (such as zsh), this may not work. Even if you are using bash, it may be invoked as sh and thus it is running in POSIX compatibility mode. You could try `set +o posix; . ~/.profile > /dev/null; whatever`

        If the code still doesn't work, try this for debugging so that you see what commands the shell runs: my $result = `set -v; set +o posix; . ~/.profile > /dev/null; whatever`

        Also, you might want to move the shell function from your profile to a separate shell script, so that you don't have to run the whole profile from our perl script. (You can still source the separate file from your profile.)

Re: Calling Shell funtion in Perl script
by northwind (Hermit) on May 24, 2005 at 15:12 UTC

    Because you created this function, I am assuming it is not sitting in /usr/bin/ or some such equivalent.  You have three options to get this to work: 

    • modify your shell PATH variable to include the path to where this program resides
    • use chdir from within your perl script to move to where the program resides
    • specify the absolute path within the `` as so `/{fullpath goes here}/pscnt $inv_app_name $parameter`
    Also, (I know this sounds basic) don't forget to check if the program has its execute bit set; I've seen sillier things overlooked...

    Update:  I just noticed you created this shell script in your .profile; if possible don't do that.  .profile is normally for configuration settings and other such stuff.  Instead, put your shell script in a seperate file with (I think) #!/usr/bin/sh (or replace the sh with whatever shell happens to be the one you want the script to run under) as your first line; then set the execute bit on the new file.

      I think the OP is saying he has a function, so it's not a program or an issue of setting the right path. My assumption is that his .profile has a line like:
      function pscnt { some_ps_commands_here }
      And he wants that invoked .. But some-what related to your suggestion, my suggestion to him is that he simply make pscnt a program (create a pscnt executable script in /usr/bin or somewhere in the PATH) and then call it.
      Well, we can't know for sure. But he used the exact term "function" rather than, say, "script" or "program". Now shells do support functions that are not stored in executable files - well, at least bash does!
      Sorry, I want to keep this function ONLY in my .profile.
        why? what would be wrong with a ~/bin/pscnt file?