0

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.

#!/bin/bash

REPOS=/var/opt/gitlab/git-data/repositories/user

for i in $(ls $REPOS)
do
        DEPLOY_DIR=/home/user/public_html/"$i"/
        POST_RECEIVE_DIR=$REPOS/"$i".git/hooks/post-receive

        echo -e '
from, to, branch = ARGF.read.split " "\r
\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
' > $POST_RECEIVE_DIR
        chmod +x $POST_RECEIVE_DIR

done

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.

3
  • Useless use of $(ls $REPOS). Better would be: for i in $REPOS/*.
    – iamauser
    Jan 1, 2016 at 18:42
  • @iamauser - how is that better?
    – mikeserv
    Jan 1, 2016 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, 2016 at 20:05

2 Answers 2

1

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
     hi
     ijaz@ijaz-HP-EliteBook-8560p:~$ echo hello>test1
     ijaz@ijaz-HP-EliteBook-8560p:~$ cat test1
     hello
     ijaz@ijaz-HP-EliteBook-8560p:~$ echo hello1>>test1
     ijaz@ijaz-HP-EliteBook-8560p:~$ cat test1
     hello
     hello1
     ijaz@ijaz-HP-EliteBook-8560p:~$ 
6
  • 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, 2016 at 19:23
  • no , a single > in loop will overwrite the old value by the new one
    – Ijaz Ahmad
    Jan 1, 2016 at 19:24
  • indeed - it cant do that without output.
    – mikeserv
    Jan 1, 2016 at 19:25
  • that's good. now can you do something about the $IFS, shell glob and echo backslash interpretations?
    – mikeserv
    Jan 1, 2016 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, 2016 at 20:13
0

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}'"
__EOF

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

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .