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.

Say I have a long path such as:

/a/b/c/d/e/f

I would like to run a command only on each of the subpaths of the path:

e.g. If my command is cmd, I am looking for a one-liner that can do (perhaps using a one-line loop)

cmd /a
cmd /a/b
cmd /a/b/c
cmd /a/b/c/d
cmd /a/b/c/d/e
cmd /a/b/c/d/e/f

One of the reasons why I need this (I need it for other things as well), is because I would like to give somebody from my unix group the ability to cd incrementally her way to /a/b/c/d/e/f. To do this, I think I need to run chmod g+x on each of these subpaths (not sure if there is an alternative). Note that I want to avoid chmod -R g+x /a.

I work primarily on zsh so I wonder if there is anything that takes advantage of specific zsh features.

share|improve this question
add comment

4 Answers

up vote 3 down vote accepted

Add this to your zsh config file:

function pathargs {
  local P=$1; local L=${#P}; shift
  local N=1; while [[ $N -le $L ]]; do
    [[ ($N == 1 && ${P[1]} = '/') || \
       ${P[$N]} != '/' && ($N == $L || ${P[$N+1]} == '/') ]] \
    && $@ ${P:0:$N}
    N=$(($N+1))
  done
}

Example:

% pathargs /abc/def/ghi/jkl echo
/
/abc
/abc/def
/abc/def/ghi
/abc/def/ghi/jkl

You can use it with chmod -R g+x instead of echo. The command will be called on the top-most directories first.

share|improve this answer
    
This looks great Stéphane. I'm not sure I understand the difference between using -n 1 and not using it. How are they exactly different? –  user815423426 Apr 20 '12 at 20:35
    
I removed the feature, it was the same difference as xargs and xargs -n 1. The new (and cleaner) function will always do to the latter: Call one instance of the command on every argument. –  Stéphane Gimenez Apr 20 '12 at 20:47
add comment

Something like

path=/a/b/c/d/e/f
while test "$path" != "/"; do
    chmod g+x "$path"
    path=$(dirname "$path")
done
share|improve this answer
    
Would by nice if dirname could be used recursively from the commandline, but I don't see that happen. +1 for cleanest script. –  Bernhard Apr 20 '12 at 21:14
    
You could incorporate this idea into a function like Stéphane's if you so desire. –  augurar Aug 14 '13 at 19:13
add comment

Quick to type and works in all shells:

(while [ "$PWD" != / ]; do cmd .; cd ..; done)

The parentheses keep the directory change local. Like your example, the root directory is omitted. If you want to stop if running cmd fails, add set -e; after the opening parenthesis.

share|improve this answer
add comment

How about find start_directory -type d -exec my_cmd {} \;

  • start_directory is /a in your example
  • type d indicates only directories. type f for files. Leave this argument for both files and directories.
  • my_cmd is cmd in your example
  • {} is replaced with the directory name found
  • \; don't forget it, the command won't work without it.

Example1: This will print out all full path directory names under /home:

find /home -type d -exec echo {} \;

Example2: This is your use case:

find /a -type d -exec echo chmod g+x {} \;

It prints the commands, doesn't execute them. You can check if it is really what you want and if so, you can pipe it to bash (or zsh if you wish):

find /a -type d -exec echo chmod g+x {} \; | bash
share|improve this answer
    
Thanks @jippie, but each of my subpaths contain many, many other folders on which I don't want to run my command. I would also like to avoid typing the name of the subpaths one by one (i.e. I am looking for something that can take /a/b/c/d/e/f/ directly) –  user815423426 Apr 20 '12 at 20:11
    
So use the variation with bash, but instead of piping it to bash redirect it to a file. Remove the unwanted lines, then execute the file. find /a -type d -exec echo chmod g+x {} \; > /tmp/my_commands.sh followed by vi /tmp/my_commands or a smart grep ... . then . /tmp/my_commands to execute the lines. Just don't forget the echo or all commands will be executed right away. –  jippie Apr 20 '12 at 20:19
    
This is exactly what roseck said he didn't want. –  Gilles Apr 20 '12 at 23:47
add comment

Your Answer

 
discard

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.