简体   繁体   中英

shell $ character overwrites the previous variable

I'm trying to write a script on shell but I'm stucked on a point.

I have a program creating data daily and puting it to a directory like this: home/meee/data/2013/07/22/mydata

My problem is I'm trying to change directory using date. Here is my script:

#!/bin/sh

x=$(date -u -v-2H "+%Y-%m-%d")
echo $x
year=$(echo $x | cut -d"-" -f1)
month=$(echo $x | cut -d"-" -f2)
day=$(echo $x | cut -d"-" -f3)
echo $year
echo $month
echo $day

d1='/home/sensor/data/'${year}/${month}
echo $d1

There is no problem related to year, day, month , they are working. But the output of echo d1 is /07me/sensor/data/2013 . Similarly, when I write echo $year$day it gives 2312 (characters of day is overwritten on the first two characater of the year)

I tried many other syntax like instead of ' character put " or leave it empty. Removing { and so on. But nothing changed.

Shortly, when I write two variable ($var1 $var2) in same line the second $ behaves like go to the beginning of the line and start overwriting the first variable.

I've been looking for that but there is nothing related to that or I couldn't find anything related and there are a lot of solution in Stackoverflow that solves the problem using $var1$var2

What am I doing wrong, or how can I solve that.

I'm working on FreeBSD 9.0-RELEASE amd64 and using sh

Any help will be appreciated.

Thanks

Somehow, your commands are introducing carriage returns to your variables, which affect the output when the variable is not the last thing echo ed. You can confirm this by passing the value through hexdump or od :

printf "%s" "$x" | hexdump -C   # Look for 0d in the output.
printf "%s" "$year" | hexdump -C   # Look for 0d in the output.
printf "%s" "$month" | hexdump -C   # Look for 0d in the output.
printf "%s" "$day" | hexdump -C   # Look for 0d in the output.

I don't think this will fix the problem, but you can get the year, month, and day without forking so many external programs:

IFS=- read year month day <<EOF
$(date -u -v-2H "+%Y-%m-%d")
EOF

or more simply

read year month day <<EOF
$(date -u -v-2H "+%Y %m %d")
EOF

You're likely using MinGW or some other not-quite-Unix environment for Windows®, which is introducing Carriage Return (CR, \\r) characters at end-of-line (from the Unix PoV).

So change this to either:

x=$(date -u -v-2H "+%Y-%m-%d" | sed $'s/\r$//')
echo $x
year=$(echo $x | cut -d"-" -f1 | sed $'s/\r$//')
month=$(echo $x | cut -d"-" -f2 | sed $'s/\r$//')
day=$(echo $x | cut -d"-" -f3 | sed $'s/\r$//')

Or, even better:

x=$(date -u -v-2H "+%Y %m %d ")
echo $x
set -- $x
year=$1
month=$2
day=$3

Note the extra space after %d which ensures that the CR will become $4 instead of attached to the day.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM