14
submitted 1 day ago* (last edited 1 day ago) by tuckerm@feddit.online to c/programming@programming.dev

edit: I got it, see bottom of this message.

tldr: In a git post-receive hook, I'm doing npx @11ty/eleventy &, with an ampersand at the end. Yet, when I git push, I still have to wait for the output of npx @11ty/eleventy to finish before I regain control of the terminal. Why is that? And how can I just tell it to continue without waiting for the npx to finish?

Longer question:

I have a website that is being generated by a static HTML generator (I'm using 11ty). I want the site to regenerate every time I push to a specific git repo, which is hosted on my web server. I'm using the post-receive git hook to do this.

If you aren't familiar with git hooks, it's basically a bash script that goes in the .git/hooks directory that will run every time specific things happen in your repo. You can check out the sample ones that are included by default in every repo: you've got post-commit, post-receive (for the server side), etc.

So I'm using a post-receive script on the server side to call the 11ty command and regenerate the site whenver I push a new commit. It works, and it's very slick.

git will show you the output of the script whenever you push to the server. Which is also very cool, except that I'd rather not wait for that. This site will eventually get very large, so I'd rather just push something and assume that the site regenerated without actually watching the output.

The command to regenerate the site is npx @11ty/eleventy. I had assumed that putting an ampersand at the end of that would make it exit right away without waiting for the command to finish. However, it still waits for the command to finish, and git shows me the full output of that command before I can use the terminal again.

What can I do to just make that script exit right after it calls the npx command, and not actually wait for npx to finish?

The full script right now is:

#!/bin/bash  

cd ../eleventy-site  
npx @11ty/eleventy &  

edit: Thanks to the recommendations from @cecilkorik@lemmy.ca and @sin_free_for_00_days@sopuli.xyz, I tried a few more things and found something that worked. I don't understand why this works, but it does:

bash -c "npx @11ty/eleventy &" &> /dev/null  

You do have to do bash -c instead of just calling the command, and both the & inside of the quotes and after it are necessary, and the > /dev/null is necessary, too.

top 7 comments
sorted by: hot top controversial new old
[-] Cyberflunk@lemmy.world 1 points 23 hours ago

I feel like I solved this situation using pre-commit git framework.

https://pre-commit.com/

If I can find it, I'll update this.

[-] chaos@beehaw.org 5 points 1 day ago

I don't understand why this works, but it does

What was happening before was this: Git received your commits and ran the shell script. It directed the script's output stream back to Git so that it could relay it back over the connection to display on your local terminal with remote: stuck in front of it. Backgrounding the npx command was working, the shell was quitting without waiting for npx to finish. However, Git wasn't waiting for the shell script to finish, it was waiting for the output stream to close, and npx was still writing to it. You backgrounded the task but didn't give npx a new place to write its output to, so it kept using the same output stream as the shell.

Running it via bash -c means "don't run this under this bash shell, start a new one and have it just run this one command rather than waiting for a human to type a command into it."

The & inside the quote is doing what you expect, telling the subshell to background this task. As before, it'll quit once the command is running, as you told it not to wait.

The last bit is &> /dev/null which tells your original, first shell that you want this command to write somewhere else instead. Specifically, the special file /dev/null, which, like basically everything else in /dev/, is not really a file, it's special kernel magic. That one's magic trick is that when you write to it, everything works as expected except all the data is just thrown away. Great for things like this that you don't want to keep.

So, the reason this works is you're redirecting the npx output elsewhere, it just goes into a black hole where no one is actually waiting for it. The subshell isn't waiting for the command to finish, so it quits almost immediately. And then the top level shell moves on after the subshell has finished.

I don't think the subshell is necessary, if you do &> /dev/null & I think it'd be the same effect. But spawning a useless shell for a split second happens all the time anyway, probably not worth worrying about too much.

[-] tuckerm@feddit.online 2 points 1 day ago

Thanks, this is a great explanation. I'll try doing &> /dev/null & tomorrow. I'd like to find the simplest version of this for recommending to other people.

[-] 30p87@feddit.org 3 points 1 day ago

Maybe try running it (npx @11ty/eleventy) with nohup

[-] cecilkorik@lemmy.ca 1 points 1 day ago* (last edited 1 day ago)

I'm not a super-expert but I suspect it's probably still holding open the stdin and stdout file descriptors of the parent process. Try using &> /dev/null to throw them away and see if that helps. You could also try adding nohup in front of the npx, which does some weird re-parenting jazz to prevent the child process (npx) from actually being attached to the parent process so that it doesn't get auto-closed when the parent exits, which is kind of the opposite of your problem, but it might also help in this case.

Another possible option is using systemd-run --user <command> which effectively should make it into sytemd's problem

[-] tuckerm@feddit.online 1 points 1 day ago

Thanks for the suggestion; I tried both of these things and they do hide the output, but it doesn't make the post-receive script actually exit early. So git push still takes a while to finish.

this post was submitted on 07 Dec 2025
14 points (100.0% liked)

Programming

23761 readers
77 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities !webdev@programming.dev



founded 2 years ago
MODERATORS