Skip to main content
Tweeted twitter.com/#!/StackUnix/status/391315012905885696
Rollback to Revision 1
Source Link
Kyle Strand
  • 729
  • 9
  • 17

Bash 4 has a fantastic option called 'globstar' that emulates (i.e. was stolen from) zsh's ** syntax for globbing across multiple directories. However, it's somewhat crippled (for my usage, at least) by the fact that it always follows symlinks.

Is there a way to prevent ** from following symlinks? If not, is there any plan to add this feature to Bash in a future release? Until then (or if there is no such plan), can anyone suggest a decent (and convenient) workaround?

I think I've read that zsh's implementation is more flexible and doesn't have this problem, but unfortunately I can't just switch to zsh because we source a lot of bash scripts at my workplace, and I don't have the time or the know-how to convert all of them to zsh and keep them up-to-date. (I suppose it might be possible to start a Bash subshell, source the desired script, then somehow backport all the changed env vars, aliases, functions, etc into zsh, but I'm not sure how to do that, either.)

I know that I could write a function using find that would behave the way I want and then alias ** to this function, but then I couldn't do something like path/to/parent/**/child/paths and have it work correctly; the closest I could come would be something like $(** path/to/parent child/paths), where ** is aliased to a function that takes the parent path as a first argument and then includes --wholename */child/paths/* as an argument to the find command that it constructs and executes. This is awkward and ugly, and I'd really like something better. (In particular, I like that the path/**/path format easily allows the variations path/** and **/path easily and intuitively, whereas a function would turn this into ** path/ and ** '.' /path, respectively, the second of which is just terrible.)

Any thoughts?

Bash 4 has a fantastic option called 'globstar' that emulates zsh's ** syntax for globbing across multiple directories. However, it's somewhat crippled (for my usage, at least) by the fact that it always follows symlinks.

Is there a way to prevent ** from following symlinks? If not, is there any plan to add this feature to Bash in a future release? Until then (or if there is no such plan), can anyone suggest a decent (and convenient) workaround?

I think I've read that zsh's implementation is more flexible and doesn't have this problem, but unfortunately I can't just switch to zsh because we source a lot of bash scripts at my workplace, and I don't have the time or the know-how to convert all of them to zsh and keep them up-to-date. (I suppose it might be possible to start a Bash subshell, source the desired script, then somehow backport all the changed env vars, aliases, functions, etc into zsh, but I'm not sure how to do that, either.)

I know that I could write a function using find that would behave the way I want and then alias ** to this function, but then I couldn't do something like path/to/parent/**/child/paths and have it work correctly; the closest I could come would be something like $(** path/to/parent child/paths), where ** is aliased to a function that takes the parent path as a first argument and then includes --wholename */child/paths/* as an argument to the find command that it constructs and executes. This is awkward and ugly, and I'd really like something better. (In particular, I like that the path/**/path format easily allows the variations path/** and **/path easily and intuitively, whereas a function would turn this into ** path/ and ** '.' /path, respectively, the second of which is just terrible.)

Any thoughts?

Bash 4 has a fantastic option called 'globstar' that emulates (i.e. was stolen from) zsh's ** syntax for globbing across multiple directories. However, it's somewhat crippled (for my usage, at least) by the fact that it always follows symlinks.

Is there a way to prevent ** from following symlinks? If not, is there any plan to add this feature to Bash in a future release? Until then (or if there is no such plan), can anyone suggest a decent (and convenient) workaround?

I think I've read that zsh's implementation is more flexible and doesn't have this problem, but unfortunately I can't just switch to zsh because we source a lot of bash scripts at my workplace, and I don't have the time or the know-how to convert all of them to zsh and keep them up-to-date. (I suppose it might be possible to start a Bash subshell, source the desired script, then somehow backport all the changed env vars, aliases, functions, etc into zsh, but I'm not sure how to do that, either.)

I know that I could write a function using find that would behave the way I want and then alias ** to this function, but then I couldn't do something like path/to/parent/**/child/paths and have it work correctly; the closest I could come would be something like $(** path/to/parent child/paths), where ** is aliased to a function that takes the parent path as a first argument and then includes --wholename */child/paths/* as an argument to the find command that it constructs and executes. This is awkward and ugly, and I'd really like something better. (In particular, I like that the path/**/path format easily allows the variations path/** and **/path easily and intuitively, whereas a function would turn this into ** path/ and ** '.' /path, respectively, the second of which is just terrible.)

Any thoughts?

That's not stealing, its the whole point of having open source software. We should copy each other's code, that's a good thing.
Source Link
terdon
  • 252.7k
  • 69
  • 481
  • 719

Bash 4 has a fantastic option called 'globstar' that emulates (i.e. was stolen from) zsh's ** syntax for globbing across multiple directories. However, it's somewhat crippled (for my usage, at least) by the fact that it always follows symlinks.

Is there a way to prevent ** from following symlinks? If not, is there any plan to add this feature to Bash in a future release? Until then (or if there is no such plan), can anyone suggest a decent (and convenient) workaround?

I think I've read that zsh's implementation is more flexible and doesn't have this problem, but unfortunately I can't just switch to zsh because we source a lot of bash scripts at my workplace, and I don't have the time or the know-how to convert all of them to zsh and keep them up-to-date. (I suppose it might be possible to start a Bash subshell, source the desired script, then somehow backport all the changed env vars, aliases, functions, etc into zsh, but I'm not sure how to do that, either.)

I know that I could write a function using find that would behave the way I want and then alias ** to this function, but then I couldn't do something like path/to/parent/**/child/paths and have it work correctly; the closest I could come would be something like $(** path/to/parent child/paths), where ** is aliased to a function that takes the parent path as a first argument and then includes --wholename */child/paths/* as an argument to the find command that it constructs and executes. This is awkward and ugly, and I'd really like something better. (In particular, I like that the path/**/path format easily allows the variations path/** and **/path easily and intuitively, whereas a function would turn this into ** path/ and ** '.' /path, respectively, the second of which is just terrible.)

Any thoughts?

Bash 4 has a fantastic option called 'globstar' that emulates (i.e. was stolen from) zsh's ** syntax for globbing across multiple directories. However, it's somewhat crippled (for my usage, at least) by the fact that it always follows symlinks.

Is there a way to prevent ** from following symlinks? If not, is there any plan to add this feature to Bash in a future release? Until then (or if there is no such plan), can anyone suggest a decent (and convenient) workaround?

I think I've read that zsh's implementation is more flexible and doesn't have this problem, but unfortunately I can't just switch to zsh because we source a lot of bash scripts at my workplace, and I don't have the time or the know-how to convert all of them to zsh and keep them up-to-date. (I suppose it might be possible to start a Bash subshell, source the desired script, then somehow backport all the changed env vars, aliases, functions, etc into zsh, but I'm not sure how to do that, either.)

I know that I could write a function using find that would behave the way I want and then alias ** to this function, but then I couldn't do something like path/to/parent/**/child/paths and have it work correctly; the closest I could come would be something like $(** path/to/parent child/paths), where ** is aliased to a function that takes the parent path as a first argument and then includes --wholename */child/paths/* as an argument to the find command that it constructs and executes. This is awkward and ugly, and I'd really like something better. (In particular, I like that the path/**/path format easily allows the variations path/** and **/path easily and intuitively, whereas a function would turn this into ** path/ and ** '.' /path, respectively, the second of which is just terrible.)

Any thoughts?

Bash 4 has a fantastic option called 'globstar' that emulates zsh's ** syntax for globbing across multiple directories. However, it's somewhat crippled (for my usage, at least) by the fact that it always follows symlinks.

Is there a way to prevent ** from following symlinks? If not, is there any plan to add this feature to Bash in a future release? Until then (or if there is no such plan), can anyone suggest a decent (and convenient) workaround?

I think I've read that zsh's implementation is more flexible and doesn't have this problem, but unfortunately I can't just switch to zsh because we source a lot of bash scripts at my workplace, and I don't have the time or the know-how to convert all of them to zsh and keep them up-to-date. (I suppose it might be possible to start a Bash subshell, source the desired script, then somehow backport all the changed env vars, aliases, functions, etc into zsh, but I'm not sure how to do that, either.)

I know that I could write a function using find that would behave the way I want and then alias ** to this function, but then I couldn't do something like path/to/parent/**/child/paths and have it work correctly; the closest I could come would be something like $(** path/to/parent child/paths), where ** is aliased to a function that takes the parent path as a first argument and then includes --wholename */child/paths/* as an argument to the find command that it constructs and executes. This is awkward and ugly, and I'd really like something better. (In particular, I like that the path/**/path format easily allows the variations path/** and **/path easily and intuitively, whereas a function would turn this into ** path/ and ** '.' /path, respectively, the second of which is just terrible.)

Any thoughts?

Source Link
Kyle Strand
  • 729
  • 9
  • 17

Force Bash 4 'globstar' option to ignore symlinks

Bash 4 has a fantastic option called 'globstar' that emulates (i.e. was stolen from) zsh's ** syntax for globbing across multiple directories. However, it's somewhat crippled (for my usage, at least) by the fact that it always follows symlinks.

Is there a way to prevent ** from following symlinks? If not, is there any plan to add this feature to Bash in a future release? Until then (or if there is no such plan), can anyone suggest a decent (and convenient) workaround?

I think I've read that zsh's implementation is more flexible and doesn't have this problem, but unfortunately I can't just switch to zsh because we source a lot of bash scripts at my workplace, and I don't have the time or the know-how to convert all of them to zsh and keep them up-to-date. (I suppose it might be possible to start a Bash subshell, source the desired script, then somehow backport all the changed env vars, aliases, functions, etc into zsh, but I'm not sure how to do that, either.)

I know that I could write a function using find that would behave the way I want and then alias ** to this function, but then I couldn't do something like path/to/parent/**/child/paths and have it work correctly; the closest I could come would be something like $(** path/to/parent child/paths), where ** is aliased to a function that takes the parent path as a first argument and then includes --wholename */child/paths/* as an argument to the find command that it constructs and executes. This is awkward and ugly, and I'd really like something better. (In particular, I like that the path/**/path format easily allows the variations path/** and **/path easily and intuitively, whereas a function would turn this into ** path/ and ** '.' /path, respectively, the second of which is just terrible.)

Any thoughts?