ZSH/Shell variable assignment/usage

68,878

Solution 1

Two things are going wrong here.

Firstly, your first snippet is not doing what i think you think it is. Try removing the second line, the echo. It still prints the date, right? Because this:

DATE= date +'20%y-%m-%d'

Is not a variable assignment - it's an invocation of date with an auxiliary environment variable (the general syntax is VAR_NAME=VAR_VALUE COMMAND). You mean this:

DATE=$(date +'20%y-%m-%d')

Your second snippet will still fail, but differently. Again, you're using the invoke-with-environment syntax instead of assignment. You mean:

# note the lack of a space after the equals sign
FILE="~/path/to/_posts/$DATE-$1.markdown"

I think that should do the trick.

Disclaimer: while i know bash very well, i only started using zsh recently; there may be zshisms at work here that i'm not aware of.

Solution 2

Learn about what a shell calls 'expansion'. There are several kinds, performed in a particular order:

The order of word expansion is as follows:

  1. tilde expansion
  2. parameter expansion
  3. command substitution
  4. arithmetic expansion
  5. pathname expansion, unless set -f is in effect
  6. quote removal, always performed last

Note that tilde expansion is only performed when the tilde is not quoted; viz.:

$ FILE="~/.zshrc"
$ echo $FILE
~/.zshrc
$ FILE=~./zshrc
$ echo $FILE
/home/user42/.zshrc

And there must be no spaces around the = in variable assignments.

Since you asked in a comment where to learn shell programming, there are several options:

  • Read the shell's manual page man zsh
  • Read the specification of the POSIX shell, http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html, especially if you want to run your scripts on different operating systems (and you will find yourself in that situation one fine day!)
  • Read books about shell programming.
  • Hang out in the usenet newsgroup comp.unix.shell where a lot of shell wizards answer questions
Share:
68,878

Related videos on Youtube

HaaR
Author by

HaaR

@tallguyrob

Updated on September 09, 2020

Comments

  • HaaR
    HaaR over 3 years

    I use ZSH for my terminal shell, and whilst I've written several functions to automate specific tasks, I've never really attempted anything that requires the functionality I'm after at the moment.

    I've recently re-written a blog using Jekyll and I want to automate the production of blog posts and finally the uploading of the newly produced files to my server using something like scp.

    I'm slightly confused about the variable bindings/usage in ZSH; for example:

    DATE= date +'20%y-%m-%d'
    echo $DATE
    

    correctly outputs 2011-08-23 as I'd expect.

    But when I try:

    DATE= date +'20%y-%m-%d'
    FILE= "~/path/to/_posts/$DATE-$1.markdown"
    echo $FILE
    

    It outputs:

    2011-08-23
    blog.sh: line 4: ~/path/to/_posts/-.markdown: No such file or directory
    

    And when run with what I'd be wanting the blog title to be (ignoring the fact the string needs to be manipulated to make it more url friendly and that the route path/to doesn't exist)

    i.e. blog "blog title", outputs:

    2011-08-23
    blog.sh: line 4: ~/path/to/_posts/-blog title.markdown: No such file or directory
    

    Why is $DATE printing above the call to print $FILE rather than the string being included in $FILE?

    • Keith Thompson
      Keith Thompson over 12 years
      date +%Y-%m-%d is cleaner than date +20%y-%m-%d. date +%F is even cleaner. (This assumes your date command supports these formats; GNU date does, but others may not.)
  • HaaR
    HaaR over 12 years
    Much appreciated, works exactly as I wanted. Where abouts did you learn about bash, specifically things such as invoke-with-environment and the like? I'm likely to run into further problems and having somewhere to refer to would help a lot.
  • Tom Anderson
    Tom Anderson over 12 years
    Kid, i learned my shell scripting on the street. Seriously. Metaphorically, but seriously. I've been using a unix command line on a daily basis since 1998, with the occasional bit of scripting, and i've been doing serious scripting as part of my job for a few years. I work with other people who know scripting well and learn from them. I ask questions on newsgroups. I read scripts in packages i use. I read good documentation when i find it - which for shell script, is sadly not often.
  • Tom Anderson
    Tom Anderson over 12 years
    The three documents really worth reading are the patchy but indispensable Advanced Bash-Scripting Guide, the pleasingly good but rather daunting Bash Reference Manual, and, of course, man bash. You should also read the excellent advice of Richard Kettlewell and David Pashley.
  • Keshav
    Keshav about 2 years
    so in the original code, does the beginning DATE= (with the space) do anything? What is the difference between that whole line and just the part after date +...?
  • Tom Anderson
    Tom Anderson about 2 years
    @Keshav The beginning DATE= followed by a space runs the following date command in an environment in which the environment variable DATE is defined to be the empty string. If you wrote DATE=potato date +'20%y-%m-%d' it would do that but with DATE defined to be "potato". The empty string is just the simplest case of doing this! The env command prints out the environment variables, so try comparing the output of env, DATE= env and DATE=potato env.