Here's what I'm trying to do:
I have several git repos. I want to setup a push-to-deploy script for each of them. being so lazy to do that for each and every repo, I wanted to script it.

My script generates a post-receive file for each repo.



for i in $(ls $REPOS)

        echo -e '
from, to, branch = ARGF.read.split " "\r
 # 3. Copy files to deploy directory\r
deploy_to_dir = File.expand_path('$DEPLOY_DIR')\r
`GIT_WORK_TREE="#{deploy_to_dir}" git checkout -f master`\r
puts "DEPLOY: master(#{to}) copied to '#{deploy_to_dir}'"\r
        chmod +x $POST_RECEIVE_DIR


Notice that the only part that changes in the generated file is where $DEPLOY_DIR lies.
And $DEPLOY_DIR changes with each iteration.
The problem is: ALL the generated files have the LAST value of $DEPLOY_DIR.

To debug I tried to echo the variable values in various places in the script and they all produce the desired outputs. I thought it could be a problem with the buffers not being flushed. so I tried to use the sync command. I tried using cat instead of echo. I tried to pass the file as a parameter to a python script where I write to the file and flush the buffer.

All failed to work.

  • Useless use of $(ls $REPOS). Better would be: for i in $REPOS/*. – iamauser Jan 1 '16 at 18:42
  • @iamauser - how is that better? – mikeserv Jan 1 '16 at 19:19
  • Have you tried to write to one of these files manually, and see if all of them change? They may all be symbolic links to the same file. Otherwise, I would suggest you edit your answer, and try to walk us through creating a minimal scenario to reproduce the error. – Amir Jan 1 '16 at 20:05

The answer is hidden in your question.

 echo $variable > file in a loop outputs only the last value of variable

will obviously output the last value only.

instead the answer is

echo $variable >> file in a loop outputs all the values of variable

> overwrites a value while >> appends it. Therefore , if you are using only > in a loop , it will keep overwriting , and only the last value will be there in the file at the end

     ijaz@ijaz-HP-EliteBook-8560p:~$ echo hi>test1
     ijaz@ijaz-HP-EliteBook-8560p:~$ cat test1
     ijaz@ijaz-HP-EliteBook-8560p:~$ echo hello>test1
     ijaz@ijaz-HP-EliteBook-8560p:~$ cat test1
     ijaz@ijaz-HP-EliteBook-8560p:~$ echo hello1>>test1
     ijaz@ijaz-HP-EliteBook-8560p:~$ cat test1
| improve this answer | |
  • this is incorrect - both forms output all values. at least, both forms do after first interpreting those values for $IFS splitting and shell globs by default, and, for a standard echo, for \\ backslash escapes as well. – mikeserv Jan 1 '16 at 19:23
  • no , a single > in loop will overwrite the old value by the new one – Ijaz Ahmad Khan Jan 1 '16 at 19:24
  • indeed - it cant do that without output. – mikeserv Jan 1 '16 at 19:25
  • that's good. now can you do something about the $IFS, shell glob and echo backslash interpretations? – mikeserv Jan 1 '16 at 19:33
  • This answer addresses the OP’s title, but not the actual question. If you look closely, you will see that each time OP uses >, it’s writing to a different file, and all the files end up undesirably having the same contents. – Amir Jan 1 '16 at 20:13

It seems to me that you have a quoting error somewhere.

Try using a "here document" to output the script:

    cat <<__EOF >"$POST_RECEIVE_DIR"
from, to, branch = ARGF.read.split " "

# 3. Copy files to deploy directory
deploy_to_dir = File.expand_path('$DEPLOY_DIR')
GIT_WORK_TREE="#{deploy_to_dir}" git checkout -f master
puts "DEPLOY: master(#{to}) copied to '#{deploy_to_dir}'"

Also, what's with the \rs? Are you trying to write DOS files?

| improve this answer | |
  • echo doesnt read stdin. it echoes arguments. – mikeserv Jan 1 '16 at 18:17
  • Sorry, should have used cat. Will edit the answer. – Beat Bolli Jan 1 '16 at 18:31
  • cat -e is not quite the same as echo -e. – muru Jan 1 '16 at 19:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.