Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

The context of this question is the hg-ssh script. It is helpful but not critical to know something about Mercurial. This script sets up a forced command using public keys so the given public key setup on the server will only allow the owner of the corresponding private key to push to a permitted set of repositories on the server. This forced commands is usually prefixed to the public key in the file ~/.ssh/authorized_keys on the server. With regard to this permitted set, the documentation before the script in the link above says:

You can use pattern matching of your normal shell, e.g.:
command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"

The idea is to permit only pushing to repositories on the server that match this pattern. I've been using hg-ssh with the forced command

command="cd /srv/hg && /usr/local/bin/hg-ssh * */* */*/* */*/*/*",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa [...]

to match all repositories (up to some number of path components) under /srv/hg, using shell globbing. I belatedly realized that it is not matching paths which contain components starting with .. My current non-working example is the MQ repository /srv/hg/faheem/bixfile/.hg/patches. So, my question is, can I select a pattern that corresponds to all paths? I would prefer to use shell globbing, which are less of a headache than regular expressions in general, but I'd take a regular expression if globbing is not an option.

share|improve this question
I was kindly pointed to unix.stackexchange.com/questions/6393/… by Gilles. I wonder if sticking in a shopt -s dotglob before the command would work. –  Faheem Mitha Jul 3 '11 at 21:09
add comment

1 Answer

up vote 2 down vote accepted

For recursive matching, the right tool is often find. Since you want to match all files in the current directory and its subdirectories recursively, but only down to a certain depth, specify -maxdepth. This isn't in POSIX, but exists on all current *BSD and in GNU find (Linux, Cygwin) and in Busybox (embedded Linux) so it's a safe bet that you have it. -exec … {} + is a relatively recent addition to POSIX, but it's been in GNU and FreeBSD/NetBSD/OSX for a while now.

cd /srv/hg && find . -type d -maxdepth 3 -exec /usr/local/bin/hg-ssh {} +

(I added -type d because you seem to want to match directories only, even though your attempt with * */* etc. matches files of all types.)

share|improve this answer
Ok, thanks. How would this look exactly, in the context of the script as posted above, ie command="cd /srv/hg && /usr/local/bin/hg-ssh * */* */*/* */*/*/*",no-port-forwarding,...? Does everything up to the curly brackets go inside the command? Also, really, the idea is to match only the directories, not the files, since a repository can only correspond to a directory, and not a file. –  Faheem Mitha Jul 3 '11 at 21:20
@FaheemMitha Everything, from cd to +, is the shell command. I copied what you did, matching all files regardless of type. If you want to match only directories, add -type d before -exec. But I wonder if this is really what you want (note that I know nothing about hg-ssh): are you looking for .hg directories? –  Gilles Jul 3 '11 at 21:25
No, all directories are possible Mercurial repositories. The example I gave (/srv/hg/faheem/bixfile/.hg/patches) is the special case of a MQ repository, which lives inside the .hg directory corresponding to another Mercurial repository. I tried it and got remote: find: Expected a positive decimal integer argument to -mindepth, but got '-maxdepth'. Can one just leave mindepth out, or does it need to be given a number? –  Faheem Mitha Jul 3 '11 at 21:42
It works if I take out -mindepth, but does it then default to mindepth 1? I'm currently using command="cd /srv/hg && find . -maxdepth 4 -type d -exec /usr/local/bin/hg-ssh {} +". –  Faheem Mitha Jul 3 '11 at 21:50
@FaheemMitha I meant -mindepth 1 to exclude . (depth 0), but I guess you want to include it? So no -mindepth. –  Gilles Jul 3 '11 at 21:55
show 3 more comments

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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