ksh storing result of a command to a variable

后端 未结 5 883
清酒与你
清酒与你 2021-01-13 15:55

I want to store the result of a command to a variable in my shell script. I cant seem to get it to work. I want the most recently dated file in the directory.



        
相关标签:
5条回答
  • 2021-01-13 16:15

    You want $() (preferred) or backticks (``) (older style), rather than single quotes:

    PRODUCT=$(ls -t /some/dir/file* | head -1 | xargs -n1 basename)
    

    or

    PRODUCT=`ls -t /some/dir/file* | head -1 | xargs -n1 basename`
    
    0 讨论(0)
  • 2021-01-13 16:19

    you have two options, either $ or backsticks`.

    1) x=$(ls -t /some/dir/file* | head -1 | xargs -n1 basename)

    or

    2) x=`ls -t /some/dir/file* | head -1 | xargs -n1 basename`

    echo $x
    

    Edit: removing unnecessary bracket for (2).

    0 讨论(0)
  • 2021-01-13 16:22

    The problem that you're having is that the command needs to be surrounded by back-ticks rather than single quotes. This is known as 'Command Substitution'.

    Bash allows you to use $() for command substitution, but this is not available in all shells. I don't know if it's available in KSH; if it is, it's probably not available in all versions.

    If the $() syntax is available in your version of ksh, you should definitely use it; it's easier to read (back ticks are too easy to confuse with single quotes); back-ticks are also hard to nest.

    This only addresses one of the problems with your command, however: ls returns directories as well as files, so if the most recent thing modified in the specified directory is a sub-directory, that is what you will see.

    If you only want to see files, I suggest using some version of the following (I'm using Bash, which supports default variables, you'll probably have to play around with the syntax of $1)

    lastfile () 
    { 
        find ${1:-.} -maxdepth 1 -type f -printf "%T+ %p\n" | sort -n | tail -1 | sed 's/[^[:space:]]\+ //'
    }
    

    This runs find on the directory, and only pulls files from that directory. It formats all of the files like this:

    2012-08-29+16:21:40.0000000000 ./.sqlite_history
    2013-01-14+08:52:14.0000000000 ./.davmail.properties
    2012-04-04+16:16:40.0000000000 ./.DS_Store
    2010-04-21+15:49:00.0000000000 ./.joe_state
    2008-09-05+17:15:28.0000000000 ./.hplip.conf
    2012-01-31+13:12:28.0000000000 ./.oneclick
    

    sorts the list, takes the last line, and chops off everything before the first space.

    0 讨论(0)
  • 2021-01-13 16:23

    You need both quotes to ensure you keep the name even if it contains spaces, and also in case you later want more than 1 file, and "$(..)" to run commands in background

    I believe you also need the '-1' option to ls, otherwise you could have several names per lines (you only keep 1 line, but it could be several files)

    PRODUCT="$(ls -1t /some/dir/file* | head -1 | xargs -n1 basename)"
    

    Please do not put space around the "=" variable assignments (as I saw on other solutions here) , as it's not very compatible as well.

    0 讨论(0)
  • 2021-01-13 16:33

    I would do something like:

    Your version corrected:

    PRODUCT=$(ls -t /some/dir/file* | head -1 | xargs -n1 basename)
    

    Or simpler:

    PRODUCT=$(cd /some/dir && ls -1t file* | head -1)
    
    • change to the directory
    • list one filename per line and sort by time/date
    • grab the first line
    0 讨论(0)
提交回复
热议问题