Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZSH/Shell variable assignment/usage

Tags:

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?

like image 220
HaaR Avatar asked Aug 23 '11 21:08

HaaR


People also ask

How do you assign a value to a variable in bash?

If the value you assign to a variable includes spaces, they must be in quotation marks when you assign them to the variable. This is because, by default, Bash uses a space as a delimiter. Bash sees the space before “Geek” as an indication that a new command is starting.

How do you set a value to a variable in Linux?

A variable is a character string to which we assign a value. The value assigned could be a number, text, filename, device, or any other type of data. A variable is nothing more than a pointer to the actual data. The shell enables you to create, assign, and delete variables.


2 Answers

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.

like image 110
Tom Anderson Avatar answered Sep 22 '22 06:09

Tom Anderson


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
like image 23
Jens Avatar answered Sep 21 '22 06:09

Jens