Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.debian.user > #269730 > unrolled thread
| Started by | Northwind <nw@secubox.org> |
|---|---|
| First post | 2024-05-31 00:30 +0200 |
| Last post | 2024-05-31 03:30 +0200 |
| Articles | 20 on this page of 27 — 10 participants |
Back to article view | Back to linux.debian.user
tree with dir size Northwind <nw@secubox.org> - 2024-05-31 00:30 +0200
Re: tree with dir size eben@gmx.us - 2024-05-31 01:00 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-05-31 01:00 +0200
Re: tree with dir size Northwind <nw@secubox.org> - 2024-05-31 01:00 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-05-31 01:10 +0200
Re: tree with dir size eben@gmx.us - 2024-05-31 02:10 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-05-31 02:20 +0200
Re: tree with dir size Franco Martelli <martellif67@gmail.com> - 2024-05-31 21:20 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-05-31 22:10 +0200
Re: tree with dir size David Wright <deblis@lionunicorn.co.uk> - 2024-06-01 04:40 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-06-01 05:20 +0200
Re: tree with dir size Lee <ler762@gmail.com> - 2024-06-01 16:20 +0200
Re: tree with dir size Franco Martelli <martellif67@gmail.com> - 2024-06-03 16:00 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-06-03 16:40 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-06-03 21:10 +0200
Re: tree with dir size David Wright <deblis@lionunicorn.co.uk> - 2024-06-04 02:40 +0200
Re: tree with dir size Franco Martelli <martellif67@gmail.com> - 2024-06-03 22:50 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-06-04 00:30 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-06-04 03:50 +0200
Re: tree with dir size Greg Wooledge <greg@wooledge.org> - 2024-06-04 16:50 +0200
Re: tree with dir size Franco Martelli <martellif67@gmail.com> - 2024-06-04 16:50 +0200
Re: tree with dir size Andy Smith <andy@strugglers.net> - 2024-06-03 16:40 +0200
Re: tree with dir size <tomas@tuxteam.de> - 2024-06-03 19:10 +0200
Re: tree with dir size Franco Martelli <martellif67@gmail.com> - 2024-06-03 23:00 +0200
Re: tree with dir size <tomas@tuxteam.de> - 2024-06-03 16:40 +0200
Re: tree with dir size Sridhar M A <alaymari@gmail.com> - 2024-05-31 02:50 +0200
Re: tree with dir size Felix Miata <mrmazda@earthlink.net> - 2024-05-31 03:30 +0200
Page 1 of 2 [1] 2 Next page →
| From | Northwind <nw@secubox.org> |
|---|---|
| Date | 2024-05-31 00:30 +0200 |
| Subject | tree with dir size |
| Message-ID | <IJWrv-gZp6-5@gated-at.bofh.it> |
Hello, is there a command that shows dir/subdir structure like `tree`, but for each dir has the size in results as well? Thanks.
[toc] | [next] | [standalone]
| From | eben@gmx.us |
|---|---|
| Date | 2024-05-31 01:00 +0200 |
| Message-ID | <IJWUx-gZyF-3@gated-at.bofh.it> |
| In reply to | #269730 |
On 5/30/24 18:28, Northwind wrote: > Hello, > > is there a command that shows dir/subdir structure like `tree`, but for each > dir has the size in results as well? It looks like "tree --du" should do it, but "tree -d --du -h" says ├── [452K] Documents when du says it's 787M. -- When we've nuked the world to a cinder, the cockroaches picking over the remains will be crawling over the remaining artifacts and wondering what "PC LOAD LETTER" means. -- PC / ASR
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-05-31 01:00 +0200 |
| Message-ID | <IJWUx-gZyF-1@gated-at.bofh.it> |
| In reply to | #269732 |
On Thu, May 30, 2024 at 06:51:30PM -0400, eben@gmx.us wrote: > It looks like "tree --du" should do it, but "tree -d --du -h" says > > ├── [452K] Documents > > when du says it's 787M. Well, that sounds like one of the numbers includes subdirectories and the other only includes files in the immediate directory. The question is: which one do you want?
[toc] | [prev] | [next] | [standalone]
| From | Northwind <nw@secubox.org> |
|---|---|
| Date | 2024-05-31 01:00 +0200 |
| Message-ID | <IJWUx-gZyF-7@gated-at.bofh.it> |
| In reply to | #269733 |
both the size of current path and subdir should be expected. thanks. > The question is: which one do you want?
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-05-31 01:10 +0200 |
| Message-ID | <IJX4d-gZU0-7@gated-at.bofh.it> |
| In reply to | #269734 |
On Fri, May 31, 2024 at 06:57:27AM +0800, Northwind wrote: > both the size of current path and subdir should be expected. According to the man page, that's what it does. I just installed tree and tried it. There's a subtle behavior that I did not expect: hobbit:/usr/local$ tree -d --du -h [3.9M] . ├── [4.0K] bin ├── [4.0K] etc Those number are definitely not totals for the files in a directory. Compare: hobbit:/usr/local$ tree --du -h | less [627M] . ├── [ 81M] bin │ ├── [7.6K] addcr It looks like the -d option makes it only look at the size of the raw directory (4096 bytes, as in hobbit:/usr/local$ ls -ld bin drwxr-sr-x 2 root staff 4096 Feb 17 15:14 bin/ ) rather than the total of the files within the directory. Solution: don't use -d. But then you get all the files listed instead of just the directories. If there's a way to get the pruning of files of -d plus the total-printing of omitting -d then I don't know what it is. The best workaround I can immediately see is to include -F to put trailing slashes on the directories, and then grep for those. hobbit:/usr/local$ tree --du -h -F | grep /$ | head [627M] ./ ├── [ 81M] bin/ ├── [4.0K] etc/ ├── [4.0K] games/ ├── [126K] include/ │ └── [122K] opus/ ├── [ 42M] lib/ │ ├── [3.4M] nethackdir/ │ │ ├── [4.0K] save/ │ ├── [4.3K] pkgconfig/
[toc] | [prev] | [next] | [standalone]
| From | eben@gmx.us |
|---|---|
| Date | 2024-05-31 02:10 +0200 |
| Message-ID | <IJY0h-h0zf-5@gated-at.bofh.it> |
| In reply to | #269733 |
On 5/30/24 18:54, Greg Wooledge wrote:
> On Thu, May 30, 2024 at 06:51:30PM -0400, eben@gmx.us wrote:
>> It looks like "tree --du" should do it, but "tree -d --du -h" says
>>
>> ├── [452K] Documents
>>
>> when du says it's 787M.
>
> Well, that sounds like one of the numbers includes subdirectories and
> the other only includes files in the immediate directory.
From du(1):
--du For each directory report its size as the accumulation of
sizes of all its files and sub-directories (and their files,
and so on). The total amount of used space is also given in
the final report (like the 'du -c' command.) This option
requires tree to read the entire directory tree before
emitting it, see BUGS AND NOTES below. Implies -s.
OK, now for "du -c". From du(1):
-c, --total
produce a grand total
Well, that doesn't help much.
> The question is: which one do you want?
I'd like the size of the entire tree, and I think that's what OP wants too.
I think "du -h -S -s Documents/" gives just the files in Documents, and not
its subdirectories, and it gives 269M. "ls -ldh Documents/" says the
directory itsely takes up 36k, so I'm not sure where "tree" got that number.
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-05-31 02:20 +0200 |
| Message-ID | <IJY9X-h0Cm-5@gated-at.bofh.it> |
| In reply to | #269745 |
On Thu, May 30, 2024 at 08:04:26PM -0400, eben@gmx.us wrote: > > > It looks like "tree --du" should do it, but "tree -d --du -h" says > > > ├── [452K] Documents > I think "du -h -S -s Documents/" gives just the files in Documents, and not > its subdirectories, and it gives 269M. "ls -ldh Documents/" says the > directory itsely takes up 36k, so I'm not sure where "tree" got that number. Hmm. Guessing again, it might be the sum of all the "-d" raw directory sizes of the directory and its subdirectories, but still ignoring files? I can't fathom why the programmer(s) decided to do this, because it isn't useful to anybody, but it's the only answer I can come up with. hobbit:~$ mkdir -p /tmp/x/y hobbit:~$ tree --du -dh /tmp/x [8.0K] /tmp/x └── [4.0K] y hobbit:~$ cp /vmlinuz /tmp/x hobbit:~$ tree --du -dh /tmp/x [8.0K] /tmp/x └── [4.0K] y Confusing and useless. I still don't have a better answer than this: hobbit:~$ tree --du -Fh /tmp/x | grep /$ [7.8M] /tmp/x/ └── [4.0K] y/
[toc] | [prev] | [next] | [standalone]
| From | Franco Martelli <martellif67@gmail.com> |
|---|---|
| Date | 2024-05-31 21:20 +0200 |
| Message-ID | <IKfXb-hhoO-1@gated-at.bofh.it> |
| In reply to | #269749 |
On 31/05/24 at 02:18, Greg Wooledge wrote:
> Confusing and useless. I still don't have a better answer than this:
>
> hobbit:~$ tree --du -Fh /tmp/x | grep /$
> [7.8M]/tmp/x/
> └── [4.0K] y/
It could be improved adding the "-a" switch to show also the hidden
directories and the "--color" switch to the "grep" command but this
sadly doesn't show the expected result (colorized directories) I don't
know why:
~$ tree --du -Fah /tmp/x | grep --color /$
Me too needed to summarize the directory's size thus I wrote a bash
function to accomplish this and added it to my /etc/profile.d/local.sh file:
duhs() { IFS=$'\n\r' ; for d in $(/usr/bin/find $1 -maxdepth 1 -type d
|/usr/bin/sort) ; do du -hs $d ; done }
It doesn't show the output like "tree" does but it works nicely.
Cheers,
--
Franco Martelli
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-05-31 22:10 +0200 |
| Message-ID | <IKgJz-hhTQ-25@gated-at.bofh.it> |
| In reply to | #269776 |
On Fri, May 31, 2024 at 09:18:03PM +0200, Franco Martelli wrote:
> On 31/05/24 at 02:18, Greg Wooledge wrote:
> > Confusing and useless. I still don't have a better answer than this:
> >
> > hobbit:~$ tree --du -Fh /tmp/x | grep /$
> > [7.8M]/tmp/x/
> > └── [4.0K] y/
>
> It could be improved adding the "-a" switch to show also the hidden
> directories and the "--color" switch to the "grep" command but this sadly
> doesn't show the expected result (colorized directories) I don't know why:
>
> ~$ tree --du -Fah /tmp/x | grep --color /$
You're only coloring the trailing / characters. If you want everything
from after the last space to the end of the line, you'd want:
tree --du -Fh /usr/local | grep --color '[^[:space:]]*/$'
Of course this fails to colorize the entire directory name if there's
a space in it.
> Me too needed to summarize the directory's size thus I wrote a bash function
> to accomplish this and added it to my /etc/profile.d/local.sh file:
>
> duhs() { IFS=$'\n\r' ; for d in $(/usr/bin/find $1 -maxdepth 1 -type d
> |/usr/bin/sort) ; do du -hs $d ; done }
This, too, will fail if there are spaces in a directory name. You'd need
to quote the "$1" and "$d" at the very least. The for d in $(find) part
is also quite fragile; I see you tried to work around that by using IFS,
but that's not a full fix. Also, you never declared IFS as a local
variable in this function, so you will be altering IFS in any shell that
actually runs this function.
Consider this one instead:
hobbit:~$ duhs() { du -hs "${1:-.}"/*/; }
hobbit:~$ duhs /usr/local
81M /usr/local/bin/
4.0K /usr/local/etc/
4.0K /usr/local/games/
136K /usr/local/include/
45M /usr/local/lib/
29M /usr/local/man/
8.0K /usr/local/sbin/
2.2M /usr/local/share/
484M /usr/local/src/
44M /usr/local/tcl8.6/
In bash, a glob that ends with / will match directories only. Globs are
always sorted, so you can also drop the call to sort. The only issue
with this version is if the number of subdirectories is so large that
it triggers the "Argument list too long" error.
If you want to avoid that, you can use xargs -0:
duhs() { printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh; }
As printf is a bash builtin, it can handle an unlimited number of
arguments. So this form should work in all cases.
[toc] | [prev] | [next] | [standalone]
| From | David Wright <deblis@lionunicorn.co.uk> |
|---|---|
| Date | 2024-06-01 04:40 +0200 |
| Message-ID | <IKmOZ-hlwF-1@gated-at.bofh.it> |
| In reply to | #269777 |
On Fri 31 May 2024 at 16:03:22 (-0400), Greg Wooledge wrote: > On Fri, May 31, 2024 at 09:18:03PM +0200, Franco Martelli wrote: > > On 31/05/24 at 02:18, Greg Wooledge wrote: > > > Confusing and useless. I still don't have a better answer than this: > > > > > > hobbit:~$ tree --du -Fh /tmp/x | grep /$ > > > [7.8M]/tmp/x/ > > > └── [4.0K] y/ > > > > It could be improved adding the "-a" switch to show also the hidden > > directories and the "--color" switch to the "grep" command but this sadly > > doesn't show the expected result (colorized directories) I don't know why: > > > > ~$ tree --du -Fah /tmp/x | grep --color /$ > > You're only coloring the trailing / characters. If you want everything > from after the last space to the end of the line, you'd want: > > tree --du -Fh /usr/local | grep --color '[^[:space:]]*/$' > > Of course this fails to colorize the entire directory name if there's > a space in it. If a coloured ] is unimportant, I suppose you could use: tree --du -Fh whatever | grep --color '][[:space:]][[:space:]].*/$' Cheers, David.
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-06-01 05:20 +0200 |
| Message-ID | <IKnrH-hlZi-1@gated-at.bofh.it> |
| In reply to | #269784 |
On Fri, May 31, 2024 at 09:35:59PM -0500, David Wright wrote:
> If a coloured ] is unimportant, I suppose you could use:
>
> tree --du -Fh whatever | grep --color '][[:space:]][[:space:]].*/$'
You don't need to count spaces. Just '].*/$' would suffice. We already
know we want to start with the first ] character on the line, no matter
how many spaces follow it.
I really question the usefulness of colorizing the directory names,
but since we're already this far down the rabbit hole, we might as
well light some dynamite to make the hole deeper. I'm sure it's safe!
We're using GNU grep for coloring, so we can also use its PCRE syntax
to do "lookbehind" voodoo:
tree --du -Fh /usr/local | grep --color -P '(?<=]).*/$'
which means "start matching after a ] but don't include the ] in the
match".
[toc] | [prev] | [next] | [standalone]
| From | Lee <ler762@gmail.com> |
|---|---|
| Date | 2024-06-01 16:20 +0200 |
| Message-ID | <IKxKp-hswd-1@gated-at.bofh.it> |
| In reply to | #269786 |
On Fri, May 31, 2024 at 11:18 PM Greg Wooledge wrote: > > On Fri, May 31, 2024 at 09:35:59PM -0500, David Wright wrote: > > If a coloured ] is unimportant, I suppose you could use: > > > > tree --du -Fh whatever | grep --color '][[:space:]][[:space:]].*/$' > > You don't need to count spaces. Just '].*/$' would suffice. We already > know we want to start with the first ] character on the line, no matter > how many spaces follow it. > > I really question the usefulness of colorizing the directory names, > but since we're already this far down the rabbit hole, we might as > well light some dynamite to make the hole deeper. I'm sure it's safe! > > We're using GNU grep for coloring, so we can also use its PCRE syntax > to do "lookbehind" voodoo: > > tree --du -Fh /usr/local | grep --color -P '(?<=]).*/$' > > which means "start matching after a ] but don't include the ] in the > match". Or use '\K' to cause previously matched characters to not be included in the match: tree --du -Fah . | grep --color -P '[^]]*] \K.*/$' (which required entirely too much RTFMing to learn about '\K') Regards, Lee
[toc] | [prev] | [next] | [standalone]
| From | Franco Martelli <martellif67@gmail.com> |
|---|---|
| Date | 2024-06-03 16:00 +0200 |
| Message-ID | <ILgo9-kbf-1@gated-at.bofh.it> |
| In reply to | #269777 |
Hi Greg,
(sorry for the answer's late but I turn off the PC during the weekend) :(
On 31/05/24 at 22:03, Greg Wooledge wrote:
>> It could be improved adding the "-a" switch to show also the hidden
>> directories and the "--color" switch to the "grep" command but this sadly
>> doesn't show the expected result (colorized directories) I don't know why:
>>
>> ~$ tree --du -Fah /tmp/x | grep --color /$
> You're only coloring the trailing / characters. If you want everything
> from after the last space to the end of the line, you'd want:
>
> tree --du -Fh /usr/local | grep --color '[^[:space:]]*/$'
I realized why "tree" command doesn't colorized the directories: "tree"
detects that its std output goes through a pipe and therefore it
disables the escaped code to colorize (like also "dmesg" does).
To avoid this behavior you must use the "unbuffer" command:
unbuffer tree --du -Fah /usr/local | grep /$
You can also try:
~# unbuffer dmesg | grep snd
/usr/bin/unbuffer is part of the "expect" package.
...> If you want to avoid that, you can use xargs -0:
>
> duhs() { printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh; }
>
> As printf is a bash builtin, it can handle an unlimited number of
> arguments. So this form should work in all cases.
Thank you very much for revolutionizing my duhs() function, but sadly
this version omits to show the hidden directories. Do you have a version
that it shows also those directories? For me it's so hard to figure out
what the "${1:-.}"/*/ block does.
Again, is "man 7 glob" the right read or do you have a better one?
Cheers,
--
Franco Martelli
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-06-03 16:40 +0200 |
| Message-ID | <ILh0R-kDd-7@gated-at.bofh.it> |
| In reply to | #269866 |
On Mon, Jun 03, 2024 at 03:52:54PM +0200, Franco Martelli wrote:
> On 31/05/24 at 22:03, Greg Wooledge wrote:
> > > It could be improved adding the "-a" switch to show also the hidden
> > > directories and the "--color" switch to the "grep" command but this sadly
> > > doesn't show the expected result (colorized directories) I don't know why:
> > >
> > > ~$ tree --du -Fah /tmp/x | grep --color /$
> > You're only coloring the trailing / characters. If you want everything
> > from after the last space to the end of the line, you'd want:
> >
> > tree --du -Fh /usr/local | grep --color '[^[:space:]]*/$'
>
> I realized why "tree" command doesn't colorized the directories: "tree"
> detects that its std output goes through a pipe and therefore it disables
> the escaped code to colorize (like also "dmesg" does).
> To avoid this behavior you must use the "unbuffer" command:
>
> unbuffer tree --du -Fah /usr/local | grep /$
According to tree(1) there's a -C option which should force tree's
coloring to be always on, even when stdout goes to a pipe. But tree
never colors anything for me, even with -C and no pipe, so I don't know
what else is needed.
> ...> If you want to avoid that, you can use xargs -0:
> >
> > duhs() { printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh; }
> >
> > As printf is a bash builtin, it can handle an unlimited number of
> > arguments. So this form should work in all cases.
>
> Thank you very much for revolutionizing my duhs() function, but sadly this
> version omits to show the hidden directories. Do you have a version that it
> shows also those directories? For me it's so hard to figure out what the
> "${1:-.}"/*/ block does.
"$1" is the first argument given to the function. It can also be written
as "${1}".
"${1:-default}" is the first argument given to the function, *or* the
constant string 'default' if the first argument is empty or not given.
Therefore, "${1:-.}" is "the first argument, or default to . if no
argument is given".
Since that part is quoted, whatever value is used is taken as a string,
with no word splitting or globbing applied. That means it will handle
directory names that contain spaces, asterisks, etc.
Given the glob "x"/*/ the shell will look for all the subdirectories
of "x". The trailing / forces it to ignore anything that isn't a
directory.
You can see it in action:
hobbit:~$ printf '%s\n' /usr/local/*/
/usr/local/bin/
/usr/local/etc/
/usr/local/games/
/usr/local/include/
/usr/local/lib/
/usr/local/man/
/usr/local/sbin/
/usr/local/share/
/usr/local/src/
/usr/local/tcl8.6/
So, putting it all together, that glob says "all the subdirectories of
the first argument, or all the subdirectories of . if there was no
argument given".
Getting it to include directory names that begin with . is trickier.
The simplest way would be to turn on bash's dotglob option, and then
turn it off again at the end:
duhs() {
shopt -s dotglob
printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
shopt -u dotglob
}
But this assumes that the option was *not* already on when we entered
the function. If it was on, we've just turned it off. Another way to
do this, which doesn't permanently alter the option for the remainder
of the shell's lifetime, would be to wrap the function body in a subshell:
duhs() {
(
shopt -s dotglob
printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
)
}
The formatting choices here are legion.
There are a few other options, but they become increasingly arcane from
here. The subshell is probably the most straightforward choice. The
function is already forking child processes, so from a performance point
of view, adding a subshell won't be much worse.
I'll also throw in one last piece of information because if I don't,
someone else is likely to do it, without a good explanation.
Syntactically, the body of a shell function doesn't have to be enclosed
in curly braces. The body can be any compound command, and a curly-brace
command group is just one example of a compound command. A subshell is
another example. So, it could also be written this way:
duhs() (
shopt -s dotglob
printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
)
I'm not personally fond of this. It's extremely easy to overlook
the fact that the curly braces have been replaced with parentheses,
especially in certain fonts. Nevertheless, some people like this.
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-06-03 21:10 +0200 |
| Message-ID | <ILle9-nkr-1@gated-at.bofh.it> |
| In reply to | #269868 |
On Mon, Jun 03, 2024 at 01:11:57PM -0500, David Wright wrote:
> On Mon 03 Jun 2024 at 10:32:16 (-0400), Greg Wooledge wrote:
> > duhs() (
> > shopt -s dotglob
> > printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
> > )
> >
> > I'm not personally fond of this. It's extremely easy to overlook
> > the fact that the curly braces have been replaced with parentheses,
> I guess minimalists would make a one-liner out of that.
> Myself, I prefer verbosity, and the ability to search and find
> all my functions with /function.*{$ in less. For example,
> I write what is probably my most trivial function in .bashrc as:
>
> function _Cat_ {
> cat
> }
>
> rather than:
>
> _Cat_() { cat; }
... I feel like you've just exemplified what I was talking about, missing
the fact that the curly braces were replaced with parentheses around the
function body to force a subshell every time it's called.
It had nothing to do with how many lines of code were used. I could
have written them as
duhs() { (shopt -s dotglob; printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh); }
and
duhs() (shopt -s dotglob; printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh)
and the same point would have applied.
> function _Cat_ {
Do note that the "function" keyword is a bash/ksh extension, and not
part of POSIX sh syntax. In bash, "x()" and "function x" are identical
in behavior. In ksh, they cause two different kinds of variable scoping
behavior. Bash also allows "function x()" which ksh does not.
Just for the record.
[toc] | [prev] | [next] | [standalone]
| From | David Wright <deblis@lionunicorn.co.uk> |
|---|---|
| Date | 2024-06-04 02:40 +0200 |
| Message-ID | <ILqnv-qmI-3@gated-at.bofh.it> |
| In reply to | #269885 |
On Mon 03 Jun 2024 at 15:03:37 (-0400), Greg Wooledge wrote:
> On Mon, Jun 03, 2024 at 01:11:57PM -0500, David Wright wrote:
> > On Mon 03 Jun 2024 at 10:32:16 (-0400), Greg Wooledge wrote:
> > > duhs() (
> > > shopt -s dotglob
> > > printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
> > > )
> > >
> > > I'm not personally fond of this. It's extremely easy to overlook
> > > the fact that the curly braces have been replaced with parentheses,
>
> > I guess minimalists would make a one-liner out of that.
> > Myself, I prefer verbosity, and the ability to search and find
> > all my functions with /function.*{$ in less. For example,
> > I write what is probably my most trivial function in .bashrc as:
> >
> > function _Cat_ {
> > cat
> > }
> >
> > rather than:
> >
> > _Cat_() { cat; }
>
> ... I feel like you've just exemplified what I was talking about, missing
> the fact that the curly braces were replaced with parentheses around the
> function body to force a subshell every time it's called.
_Puss_() ( cat )
if it makes you happy; but no, you made your point about parentheses
perfectly well. It's just that _Cat_ doesn't require a subshell for
/its/ purpose.
> It had nothing to do with how many lines of code were used. I could
> have written them as
>
> duhs() { (shopt -s dotglob; printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh); }
>
> and
>
> duhs() (shopt -s dotglob; printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh)
>
> and the same point would have applied.
>
> > function _Cat_ {
>
> Do note that the "function" keyword is a bash/ksh extension, and not
> part of POSIX sh syntax. In bash, "x()" and "function x" are identical
> in behavior. In ksh, they cause two different kinds of variable scoping
> behavior. Bash also allows "function x()" which ksh does not.
>
> Just for the record.
Noted. (Franco did mention using bash, and I mentioned .bashrc.)
I'm a bit old for switching shells now!
Cheers,
David.
[toc] | [prev] | [next] | [standalone]
| From | Franco Martelli <martellif67@gmail.com> |
|---|---|
| Date | 2024-06-03 22:50 +0200 |
| Message-ID | <ILmMV-o6h-1@gated-at.bofh.it> |
| In reply to | #269868 |
On 03/06/24 at 16:32, Greg Wooledge wrote:
> duhs() {
> shopt -s dotglob
> printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
> shopt -u dotglob
> }
>
> But this assumes that the option was*not* already on when we entered
> the function. If it was on, we've just turned it off. Another way to
> do this, which doesn't permanently alter the option for the remainder
> of the shell's lifetime, would be to wrap the function body in a subshell:
>
> duhs() {
> (
> shopt -s dotglob
> printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
> )
> }
I've some issue with this function. It doesn't show the size of the
directory specified as argument, it follows the output of my original
function:
duhs1() { IFS=$'\n\r' ; for d in $(/usr/bin/find $1 -maxdepth 1 -type d
|/usr/bin/sort) ; do du -hs $d ; done }
~# duhs1 /usr/local/
88K /usr/local/ ←←←
4,0K /usr/local/bin
4,0K /usr/local/etc
...
According to the very kind Greg's explanation I tried to change the
function in this way:
duhs() {
(
shopt -s dotglob
du -sh "${1:-.}"
printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
)
}
the specified directory is shown, but the output has became messed up:
~# duhs /usr/local/
88K /usr/local/
4,0K /usr/local//bin/
4,0K /usr/local//etc/
4,0K /usr/local//games/
4,0K /usr/local//include/
4,0K /usr/local//man/
4,0K /usr/local//sbin/
56K /usr/local//share/
4,0K /usr/local//src/
and worst the size of /usr/local/share isn't 56K:
~# du -hs /usr/local/share/
60K /usr/local/share/
as it's shown by my original function:
~# duhs1 /usr/local/
88K /usr/local/
4,0K /usr/local/bin
4,0K /usr/local/etc
4,0K /usr/local/games
4,0K /usr/local/include
4,0K /usr/local/sbin
60K /usr/local/share
4,0K /usr/local/src
the /usr/local/man/ isn't listed by the "find" command because it's a
symlink:
~# ls -l /usr/local/man
lrwxrwxrwx 1 root root 9 21 giu 2023 /usr/local/man -> share/man
Is there a way to have duhs() function that it doesn't print a double
"/" at the end of the specified directory?
The size mismatch of /usr/local/share could depend by /usr/local/man is
a symlink of 4K's size to a directory embedded in /usr/local/share, am I
right?
Cheers,
--
Franco Martelli
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-06-04 00:30 +0200 |
| Message-ID | <ILolH-p9f-13@gated-at.bofh.it> |
| In reply to | #269899 |
On Mon, Jun 03, 2024 at 10:45:28PM +0200, Franco Martelli wrote:
> On 03/06/24 at 16:32, Greg Wooledge wrote:
> > duhs() {
> > (
> > shopt -s dotglob
> > printf '%s\0' "${1:-.}"/*/ | xargs -0 du -sh
> > )
> > }
>
> I've some issue with this function. It doesn't show the size of the
> directory specified as argument, it follows the output of my original
> function:
I started writing a response to this, because it seemed easy enough to
fix -- just add "${1:-.}" to the printf arguments, so it gets passed
along to du -sh, and included in the output.
But then I tested it.
hobbit:~$ du -sh /usr/local /usr/local/bin
684M /usr/local
What? Where's the second line?
hobbit:~$ du -sh /usr/local/bin /usr/local/etc
81M /usr/local/bin
4.0K /usr/local/etc
Multiple arguments are allowed....
hobbit:~$ du -sh /usr/local/bin /usr/local/etc /usr/local
81M /usr/local/bin
4.0K /usr/local/etc
603M /usr/local
You're even allowed to have a parent directory after its children...
hobbit:~$ du -sh /usr/local /usr/local/bin /usr/local/etc
684M /usr/local
... but if the parent is FIRST, the children get... swallowed up by
it? Huh? And if the parent is last, then the value shown for the
parent excludes the children that were already reported on?
Why the HELL is it like this?!
It doesn't even match its own documentation. Here's what the info
page says:
‘-s’
‘--summarize’
Display only a total for each argument.
There's supposed to be a total *FOR EACH ARGUMENT*. There isn't.
OK, I officially wash my hands of ANY solution based on du -s. If
you want to try to make it work sensibly, more power to you. As far
as I'm concerned, though, this is broken. Irreparably broken.
It looks like tree(1) is less broken, so it might be better to stick
with that, even if you have to pipe the output through grep to get what
you want.
*Sigh*.
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-06-04 03:50 +0200 |
| Message-ID | <ILrtf-qXB-3@gated-at.bofh.it> |
| In reply to | #269910 |
On Mon, Jun 03, 2024 at 07:42:17PM -0500, David Wright wrote:
> On Mon 03 Jun 2024 at 18:29:17 (-0400), Greg Wooledge wrote:
> > ‘-s’
> > ‘--summarize’
> > Display only a total for each argument.
> >
> > There's supposed to be a total *FOR EACH ARGUMENT*. There isn't.
>
> Try adding -l. The idea is that du is trying to avoid double-counting,
> so when the subdirectories come first, those ones are "used up" by
> the time it reaches the parent. When the parent is first, it's (all)
> the subdirectories instead that have been "used up".
‘-l’
‘--count-links’
Count the size of all files, even if they have appeared already (as
a hard link).
This documentation leaves a lot to be desired.
Anyway, you are correct about the result, even if the documentation gives
no realistic way to conclude such a result.
hobbit:~$ printf '%s\0' "${1:-.}" "${1:-.}"/*/ | xargs -0 du -shl
684M /usr/local
81M /usr/local/bin/
4.0K /usr/local/etc/
4.0K /usr/local/games/
136K /usr/local/include/
45M /usr/local/lib/
29M /usr/local/man/
8.0K /usr/local/sbin/
31M /usr/local/share/
484M /usr/local/src/
44M /usr/local/tcl8.6/
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2024-06-04 16:50 +0200 |
| Message-ID | <ILDE5-yuR-1@gated-at.bofh.it> |
| In reply to | #269914 |
On Tue, Jun 04, 2024 at 04:40:07PM +0200, Franco Martelli wrote:
> FYI the revision of duhs() I adopt is:
>
> duhs() { ( shopt -s dotglob; printf '%s\0' "${1:-.}" "${1:-.}"*/ | xargs -0
> du -shl ) } ↑
>
> Please note that I dropped a "/" in the "${1:-.}"/*/ block because the
> directories listed had a double "//" in their names:
That's because you're passing directories with a trailing / from your
shell. Probably because you're using tab completions.
If you pass "/usr/local" as the argument instead of
> ~# duhs /usr/local/
> 88K /usr/local/
> 4,0K /usr/local//bin/
> 4,0K /usr/local//etc/
> 4,0K /usr/local//games/
> 4,0K /usr/local//include/
> 4,0K /usr/local//man/
> 4,0K /usr/local//sbin/
> 60K /usr/local//share/
> 4,0K /usr/local//src/
you will see that you've broken it now.
If you really care about removing the double slashes from the case
where you pass an extra trailing slash in your input, you should use
parameter expansions or some other filtering to remove one of the
slashes. That would be better than breaking your function.
duhs() {
(
shopt -s dotglob
s=${1:-.}
s=${s%/}
printf '%s\0' "${s:-.}" "${s:-.}"/*/ | xargs -0 du -shl
)
}
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.debian.user
csiph-web