I think it's important to note that the cat
isn't the problem in my comment above, but shell redirection. Are you trying to restrict copying of binaries or text files? If it's binaries, then I believe you can work something out with rbash (see http://blog.bodhizazen.net/linux/how-to-restrict-access-with-rbash/).
However, if it's text files, I'm not sure how you can prevent someone from just copying from their local terminal.
I'm not sure any general SELinux solution would be helpful here. Does your application that reads files need to write data anywhere? If not and these files only need to be read by your application, you could just give your application's type read-only access to the files of the type you would like it to read and don't give it write anywhere.
I think some more information on the exact permissions required by your use-case might be helpful, sorry for the vague answer.
UPDATE - MORE SPECIFIC ANSWER
I think you can achieve what you want without SELinux, as this is how many things are handled (e.g. normal users changing their password in /etc/shadow via the passwd
command):
- Make a separate user and/or group for your commercial software (might already be done)
- Give the files read-only access by said user and/or group
- Make sure normal users do not have access to those files
- Make your executable setuid or getgid (depending on whether you used a group or user) e.g.
chmod g+s
or chmod u+s
- When users run the application, they will now have the same permissions that the application user or group has, thereby allowing read access to those specific files within the desired application.
UPDATE2 - MULTIPLE USERS AND GROUPS
If you have multiple applications and groups, you can likely achieve the functionality you are looking for with sudo
. Many people are aware of its ability to let you run commands a root, but it's usefulness goes far beyond that example. I'm not sure this an ideal setup, but it's one way to do what you're attempting.
You can still make all the application files owned by the application, but then you can make separate groups for each set of files.
This is what your /etc/sudoers
or a file in /etc/sudoers.d/
could look like:
User_Alias FILEGROUP1 = user1, user2
User_Alias FILEGROUP2 = user3, user4
Cmnd_Alias MYEDITOR = /usr/local/bin/myeditor, /usr/local/bin/mycompiler
FILEGROUP1 ALL=(:fileset1) NOPASSWD: MYEDITOR
FILEGROUP2 ALL=(:fileset2) NOPASSWD: MYEDITOR
Where user1
and user2
need access to files owned by the group fileset1
and user3
and user4
need access to files owned by the group fileset2
. You could also use groups instead of users.
The users could access their files through the editor by doing sudo -g fileset1 /usr/local/bin/myeditor
or something similar.
It might help to create some wrapper scripts for the necessary sudo -g
commands for your users, especially since it sounds like may be a graphical application.
More details:
http://www.garron.me/linux/visudo-command-sudoers-file-sudo-default-editor.html
https://serverfault.com/questions/166254/change-primary-group-with-sudo-u-g
http://linux.die.net/man/8/sudo
Please don't do this in the shell. There is no amount of tweaking that would ever make it remotely efficient. Shell loops are slow and using the shell to parse text is just bad practice. Your whole script can be replaced by this simple awk
one-liner which will be orders of magnitude faster:
awk 'BEGIN{E = exp(1);} $1>0{tot+=log($1); c++} END{m=tot/c; printf "%.2f\n", E^m}' file
For example, if I run that on a file containing the numbers from 1 to 100, I get:
$ seq 100 > file
$ awk 'BEGIN{E = exp(1);} $1>0{tot+=log($1); c++} END{m=tot/c; printf "%.2f\n", E^m}' file
37.99
In terms of speed, I tested your shell solution, your python solution and the awk I gave above on a file containing the numbers from 1 to 10000:
## Shell
$ time foo.sh
3677.54
real 1m0.720s
user 0m48.720s
sys 0m24.733s
### Python
$ time foo.py
The Geometric Mean is: 3680.827182220091
real 0m0.149s
user 0m0.121s
sys 0m0.027s
### Awk
$ time awk 'BEGIN{E = exp(1);} $1>0{tot+=log($1); c++} END{m=tot/c; printf "%.2f\n", E^m}' input.txt
3680.83
real 0m0.011s
user 0m0.010s
sys 0m0.001s
As you can see, the awk
is even faster than the python and far simpler to write. You can also make it into a "shell" script, if you like. Either like this:
#!/bin/awk -f
BEGIN{
E = exp(1);
}
$1>0{
tot+=log($1);
c++;
}
END{
m=tot/c; printf "%.2f\n", E^m
}
or by saving the command in a shell script:
#!/bin/sh
awk 'BEGIN{E = exp(1);} $1>0{tot+=log($1); c++;} END{m=tot/c; printf "%.2f\n", E^m}' "$1"
Best Answer
dd
dates from back when it was needed to translate old IBM mainframe tapes, and the block size had to match the one used to write the tape or data blocks would be skipped or truncated. (9-track tapes were finicky. Be glad they're long dead.) These days, the block size should be a multiple of the device sector size (usually 4KB, but on very recent disks may be much larger and on very small thumb drives may be smaller, but 4KB is a reasonable middle ground regardless) and the larger the better for performance. I often use 1MB block sizes with hard drives. (We have a lot more memory to throw around these days too.)