3

I am trying to run a program in a chrooted environment, and it needs /dev/random as a resource. Manually I can do ls -l on it and then create the file again with mknod c xx yy, but I need to make it automatic and I don't think these version numbers are constant from a linux version to another so that is why I have the following question :

How could I write a bash script that would extract the minor and major numbers of /dev/random and use it with mknod? I can use ls -l but I don't know how to extract a substring of it...

The exact return of ls -l /dev/random is :

crw-rw-rw- 1 root root MINOR, MAJOR mars  30 19:15 /dev/random

and the two numbers I want to extract are MINOR and MAJOR. However if there is an easier way to create the node without ls and mknod I would appreciate it.

user3779430
  • 420
  • 5
  • 16

3 Answers3

5

You can get the major and minor device numbers with stat:

MINOR=`stat -c %T /dev/random`
MAJOR=`stat -c %t /dev/random`

You can then create a device node with:

mknod mydevice c "$MAJOR" "$MINOR"

Another approach (which doesn't require the parsing of device numbers) is to use tar to create an archive with the details of the device files in:

cd /dev
tar cf /somewhere/devicefiles.tar random null [any other needed devices]

then

cd /somewhere/chroot-location
tar xf /somewhere/devicefiles.tar

This latter method has the advantage that it doesn't rely on the -c option to stat, which is a GNU extension.

psmears
  • 26,070
  • 4
  • 40
  • 48
  • FYI, from http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08 -- *The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.* – Charles Duffy Mar 30 '15 at 13:43
  • ...thus, the convention of using lower-case variable names inside scripts where possible is actually enshrined in POSIX. – Charles Duffy Mar 30 '15 at 13:45
  • @CharlesDuffy: Those comments refer to environment variables, right? – psmears Mar 30 '15 at 13:55
  • the tar command is very interesting since I wouldn't have to read /dev on the other machine, would it work if I would use ‘cp -a /dev/random‘ into my chrooted environment, tar this environment, and deploy it on a new machine? I am going to try that. – user3779430 Mar 30 '15 at 14:02
  • @psmears: Correct, but even changing a shell variable will impact the environment if any environment variable with the same name exists. Thus, if one wants to be certain of writing scripts that won't modify the system's behavior as an unintended side effect, the convention applies to all shell variables. – Charles Duffy Mar 30 '15 at 15:04
  • @CharlesDuffy: It may be a good guideline to follow, but unfortunately you can't be "certain" of that even if you do follow the convention; eg the "http_proxy" (lower case) environment variable affects the behaviour of a number of programs. It might work if (a) you stick 100% to POSIX-specified utilities, and (b) your system is 100% POSIX compliant, but that would be an unusual situation, in my experience ;-) – psmears Mar 31 '15 at 09:09
  • @psmears, sadly, yes, there are exceptions -- that doesn't mean that following the rule is no longer best practice. If I had a dollar for every time I saw someone write `for PATH in $PATHS; do`, it would at least pay for lunch. :) – Charles Duffy Mar 31 '15 at 13:15
4

A minor improvement to efficiency would be to do only one call (and to use lower-case variable names, as is conventional for all variables other than builtins and environment variables in shell):

read minor major < <(stat -c '%T %t' /dev/random)

On a GNU system, by the way, I'd suggest using cp -a to copy your explicitly whitelisted device files into the chroot during setup:

cp -a /dev/random /your/chroot/dev/random
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
1

Try this.

MAJOR=ls -l /dev/random | awk '{ print $5}'

MINOR=ls -l /dev/random | awk '{ print $6}'

Manthan Tilva
  • 3,135
  • 2
  • 17
  • 41
  • Not safe -- see the POSIX spec at http://pubs.opengroup.org/onlinepubs/009695399/utilities/ls.html -- "If the file is a character special or block special file, the size of the file may be replaced with **implementation-defined** information associated with the device in question." (emphasis added). Thus, there's no guarantee that any given version of `ls` will use a particular format for output when listing device nodes. – Charles Duffy Mar 30 '15 at 13:39
  • I did not know about awk which seems pretty interesting but the other solutions seem a lot better indeed. – user3779430 Mar 30 '15 at 13:40
  • Granted, the `stat` behavior in question isn't POSIX-defined either -- but using `-c` on a non-GNU `stat` is likely to give an outright error, whereas parsing a non-GNU `ls` can result in a silently wrong answer. – Charles Duffy Mar 30 '15 at 13:41