Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raku-native disk space usage

Purpose:

  • Save a program that writes data to disk from vain attempts of writing to a full filesystem;
  • Save bandwidth (don't download if nowhere to store);
  • Save user's and programmer's time and nerves (notify them of the problem instead of having them tearing out their hair with reading misleading error messages and "why the heck this software is not working!").

The question comes in 2 parts:

  1. Reporting storage space statistics (available, used, total etc.), either of all filesystems or of the filesystem that path in question belongs to.
  2. Reporting a filesystem error on running out of space.

Part 1

Share please NATIVE Raku alternative(s) (TIMTOWTDIBSCINABTE "Tim Toady Bicarbonate") to:

raku -e 'qqx{ df -P $*CWD }.print'

Here, raku -executes df (disk free) external program via shell quoting with interpolation qqx{}, feeding -Portable-format argument and $*CWD Current Working Directory, then .prints the df's output.


The snippet initially had been written as raku -e 'qqx{ df -hP $*CWD }.print' — with both -human-readable and -Portable — but it turned out that it is not a ubiquitously valid command. In OpenBSD 7.0, it exits with an error: df: -h and -i are incompatible with -P.
For adding human-readability, you may consider Number::Bytes::Human module

like image 660
uxer Avatar asked Aug 02 '21 10:08

uxer


2 Answers

raku -e 'run <<df -hP $*CWD>>'

If you're just outputting what df gives you on STDOUT, you don't need to do anything.

The << >> are double quoting words, so that the $*CWD will be interpolated.

like image 171
Elizabeth Mattijsen Avatar answered Oct 14 '22 07:10

Elizabeth Mattijsen


Part 1 — Reporting storage space statistics

There's no built in function for reporting storage space statistics. Options include:

  • Write Raku code (a few lines) that uses NativeCall to invoke a platform / filesystem specific system call (such as statvfs()) and uses the information returned by that call.

  • Use a suitable Raku library. FileSystem::Capacity picks and runs an external program for you, and then makes its resulting data available in a portable form.

  • Use run (or similar1) to invoke a specific external program such as df.

  • Use an Inline::* foreign language adaptor to enable invoking of a foreign PL's solution for reporting storage space statistics, and use the info it provides.2

Part 2 — Reporting running out of space

Raku seems to neatly report No space left on device:

> spurt '/tmp/failwrite', 'filesystem is full!'
Failed to write bytes to filehandle: No space left on device
  in block <unit> at <unknown file> line 1

> mkdir '/tmp/failmkdir'
Failed to create directory '/tmp/failmkdir' with mode '0o777': Failed to mkdir: No space left on device
  in block <unit> at <unknown file> line 1

(Programmers will need to avoid throwing away these exceptions.)

Footnotes

1run runs an external command without involving a shell. This guarantees that the risks attendant with involving a shell are eliminated. That said, Raku also supports use of a shell (because that can be convenient and appropriate in some scenarios). See the exchange of comments under the question (eg this one) for some brief discussion of this, and the shell doc for a summary of the risk:

All shell metacharacters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on. Shell escapes are a severe security concern and can cause confusion with unusual file names. Use run if you want to be safe.

2 Foreign language adaptors for Raku (Raku modules in the Inline:: namespace) allow Raku code to use code written in other languages. These adaptors are not part of the Raku language standard, and most are barely experimental status, if that, but, conversely, the best are in great shape and allow Raku code to use foreign libraries as if they were written for Raku. (As of 2021 Inline::Perl5 is the most polished.)

like image 30
2 revs, 2 users 78% Avatar answered Oct 14 '22 07:10

2 revs, 2 users 78%