LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-27-2019, 08:13 PM   #16
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242

Quote:
Originally Posted by crts View Post
You can use the following instead:
Code:
find . -type d -exec chmod 0755 {} +
find . -type f -exec chmod 0644 {} +
This will spawn 'chmod' only once. Personally, I prefer

Code:
chmod -R 0755 .
find . -type f -exec chmod -x {} +
I am not sure if changing file permissions twice has more overhead than processing them once but spawning one more process (find). It is, however, definitely less to type and there should not be much difference in execution time on a reasonably modern machine.
there goes all of my scripts in ~/bin got a redo them now to make them exec again. that entire recursive in my current dir if its home dir look out.
 
1 members found this post helpful.
Old 05-27-2019, 11:44 PM   #17
orbea
Senior Member
 
Registered: Feb 2015
Distribution: Slackware64-current
Posts: 1,950

Rep: Reputation: Disabled
Quote:
Originally Posted by crts View Post
You can use the following instead:
Code:
find . -type d -exec chmod 0755 {} +
find . -type f -exec chmod 0644 {} +
This will spawn 'chmod' only once. Personally, I prefer

Code:
chmod -R 0755 .
find . -type f -exec chmod -x {} +
I am not sure if changing file permissions twice has more overhead than processing them once but spawning one more process (find). It is, however, definitely less to type and there should not be much difference in execution time on a reasonably modern machine.
Its worth pointing out that some older versions of GNU find do not have this, that probably doesn't matter in practice for most people.
 
1 members found this post helpful.
Old 05-28-2019, 08:00 AM   #18
Astral Axiom
Member
 
Registered: Feb 2018
Location: Asheville, NC
Distribution: Ubuntu, Arch, Centos, Debian, Kali
Posts: 47

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by MadeInGermany View Post
Your problem is that
Code:
ls "$DIR"
strips the path, showing the bare filenames. You would need to "cd" into it, giving you some other problems.
The following is much more elegant
Code:
#! /bin/bash

DIR=$1

if [[ ! -d $DIR ]]
then
    echo "
$0 command accepts one directory as an argument, any further arguments are
ignored. You have passed something other than a directory for arg 1, please try again.
Perhaps check your spelling. Also, at least one argument must be passed in.
"
    exit 1
fi

# ls "$DIR" strips the path
# option nullglob: return nothing if nothing matches in filename glob
# option dotglob: include filenames starting with a dot (like ls -A)

shopt -s nullglob dotglob

recurse(){
  chmod 755 "$1"
  for ITEM in "$1"/*
  do
    [[ -h $ITEM ]] && continue
    if [[ -f $ITEM ]]
    then
        chmod 644 "$ITEM"
    elif [[ -d $ITEM ]]
    then
        recurse "$ITEM"
    fi
  done
}

recurse "$DIR"

echo "
New permissions are as follows:
"
ls -lR "$DIR"
Thanks so much for clearing that up, I changed my script piece by piece. First adding the wildcard to the -- $(ls $1) -- to make it -- $(ls $1/*) --, but it still did not work so I removed the ls making the line -- for Item in "$1"/* -- which resulted in a successful recursion of the directory tree passed in.

From reading in -- man bash -- I see the clever use of the "-h" option paired with "continue". If I understand correctly:
Code:
[[ -h $ITEM ]] && continue
is equivalent to:
Code:
if [[ -h $ITEM ]]
then
    continue
fi
if bash is like Java in that when doubling the -- & -- with -- && --, the second expression is not checked unless the first is false. In bash though, the single -- & -- puts a command in the background right? So I am guessing that is just the default behavior of compound expressions, unlike in Java where when using a single -- & -- the next expression is checked regardless of the true or false condition of the preceding expression ...I could be remembering that incorrectly since I only ever use the double -- && --.
Quote:
Only the function is recursive; the overhead is much smaller compared to calling the whole script.
thanks, using the function seems a better option overall, I actually abandoned the recursive script and stuck with the recursive function in a script.
Quote:
Using nullglob we can emulate an ls that does not strip the path.
Using dotglob we can emulate an ls -A (find filenames that start with a dot).
Using a glob, we cannot disable filename globbing with set -f, so we should consequently put quotes around $var in command arguments. (Note: unlike [ ], the [[ ]] is not a command. Of course you could put quotes neverheless.)
And, last but not least, do not follow symlinks! -f/-d is true if it's a file/directory or a symlink to a file/directory.
Reading in -- man bash -- I get that -- shopt -s -- enables options and that the dotglob option causes the dot files to be included in the output of -- "$1"/* --, I think. What I am not quite getting is the nullglob option:
Quote:
quoted from bash man page:

"nullglob
If set, bash allows patterns which match no files (see Pathname Expansion above) to expand to
a null string, rather than themselves."

"Pathname Expansion
If no matching filenames
are found, and the shell option nullglob is not enabled, the word is left unchanged. If the nullglob option
is set, and no matches are found, the word is removed."
So, in this script, does enabling nullglob cause an empty directory's name to be removed from the iteration list, during iteration, in the for loop? I have not added the line -- shopt -s nullglob dotglob -- to my script yet, since I do not yet understand it and do not wish to write code I do not yet understand, and the script works as I intended. What does this line do, especially where nullglob is concerned, and am I understanding what dotglob is doing correctly?
 
Old 05-28-2019, 10:00 AM   #19
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Quote:
Originally Posted by BW-userx View Post
there goes all of my scripts in ~/bin got a redo them now to make them exec again. that entire recursive in my current dir if its home dir look out.
The previously presented 'find' solutions would have had the same effect, if applied blindly. The lesson here to learn is:

Copy/Paste programming is not real programming.

Think before you type and never blindly copy/paste anything if you do not understand what it is doing.

Last edited by crts; 05-28-2019 at 02:49 PM. Reason: typo
 
1 members found this post helpful.
Old 05-28-2019, 12:17 PM   #20
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by crts View Post
The previously presented 'find; solutions would have had the same effect, if applied blindly. The lesson here to learn is:

Copy/Paste programming is not real programming.

Think before you type and never blindly copy/paste anything if you do not understand what it is doing.
you can still type in
Code:
chmod -R 0755 .
find . -type f -exec chmod -x {} +
and still get the same effect, I was mealy pointing out the dot being current dir, so if in /home/user what effects can one expect, regardless if one copy paste that, or types it in. Not everyone that may read this know what that dot is for.
 
Old 05-28-2019, 04:35 PM   #21
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,780

Rep: Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198Reputation: 1198
An exercise for nullglob:
Code:
mkdir temp
cd temp
echo "ls output:"
ls
echo "for loop output:"
for i in *
do
  echo "$i"
done
You’ll see that a "no match" becomes the search term "*", and the loop runs once with it.
With option nullglob a "no match" becomes a nullstring, and the loop does not run.

An exercise for dotglob:
Code:
mkdir temp
cd temp
touch file1 file2 .file3
echo "ls output:"
ls
echo "ls -A output:"
la -A
echo "for loop output:"
for i in *
do
  echo "$i"
done
You‘ll see that filenames starting with a dot are "hidden" by default.
With option dotglob they are treated like normal filenames i.e. the "*" shows them, just like "ls -A" does.
 
1 members found this post helpful.
Old 05-28-2019, 07:49 PM   #22
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,897

Rep: Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018
Quote:
Originally Posted by BW-userx View Post
you can still type in
Code:
chmod -R 0755 .
find . -type f -exec chmod -x {} +
and still get the same effect, I was mealy pointing out the dot being current dir, so if in /home/user what effects can one expect, regardless if one copy paste that, or types it in. Not everyone that may read this know what that dot is for.
There are a number of ways to avoid that. In GNU find "-mindepth 1" will do the job (but I believe that's a GNU extension). You could add ! -name "." to achieve the same thing. Alternatively, for a more complex example, if you wanted to only list the files that are not hidden and which are not in hidden directories you can do:
find . -type d -name ".?*" -prune -o -type f ! -name ".*" -print

That last one's useful when you're in your home dir, or a git working directory.


Anyway, the take home is that find is a very powerful but subtle tool. Well worth learning but you definitely need to be careful with it.

Always -print before you -exec !
 
Old 05-29-2019, 09:57 AM   #23
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
RTFM

Code:
chmod -R  u=rwX,g=rX,o=rX  DIR/
10 minutes reading saves days of work.
 
1 members found this post helpful.
Old 05-31-2019, 07:44 AM   #24
Astral Axiom
Member
 
Registered: Feb 2018
Location: Asheville, NC
Distribution: Ubuntu, Arch, Centos, Debian, Kali
Posts: 47

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by bigearsbilly View Post
RTFM

Code:
chmod -R  u=rwX,g=rX,o=rX  DIR/
10 minutes reading saves days of work.
I have seen several responses on the links in answer #5 that are similar to this, however, on my system at least, this sort of use of "chmod -R" gives execute privileges to all files as well as directories. It seems that whatever means are used to determine where X makes sense are not working in such a way as to be useful here.

I think this is why:
Quote:
quoted from the chmod man page:
execute/search only if the file is a directory or already has execute permission for some user (X)

Last edited by Astral Axiom; 05-31-2019 at 09:19 AM. Reason: edited to: answer #5
 
  


Reply

Tags
bash, recursion, script



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
chmod all files 644 and files 755 cope Linux - General 7 01-04-2014 10:52 PM
[SOLVED] FTP: recursive chmod (separate for directories and files) mgmax Linux - Software 11 01-29-2011 08:06 AM
[SOLVED] What's the difference between chmod 0755 file and chmod 755 file? cola Linux - Newbie 6 04-19-2010 04:29 PM
Apache: difference between chmod 644 and chmod 666 and chmod 600 for output/txt/dat? frenchn00b Programming 6 04-22-2009 01:10 PM
How can I change the directory I am currently in and all directories under it to 755? abefroman Programming 6 10-21-2005 06:15 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration