New answers tagged

0

I wrote two functions you can use together that do just that, you can limit the directory level by adding a -maxdepth $VAL parameter. # This scripts flattens the file directory # Run this script with a folder as parameter: # $ path/to/script path/to/folder #!/bin/bash rmEmptyDirs(){ local DIR="$1" for dir in "$DIR"/*/ do [ -d "${dir}" ]...


0

As a variation of the original question, if you want to see the cumulative size of files in the subdirectories: #!/bin/bash find ${1:-.} -maxdepth 1 -type d -exec du -sm {} \; | sort -nr The sizes will be displayed in Megabytes ( the m in du -sm). Other values accepted by du are -k for kilobytes, -g for gigabytes. Using -h for human-readable display is ...


0

The following sh shell loop will remove all spaces, underscores and dashes from the names of files in the current directory, taking care to not overwrite any existing files: for f in *; do test -f "$f" || continue nf=$( echo "$f" | tr -d ' _-' ) ! test -e "$nf" && echo mv "$f" "$nf" done For bash and ksh, and being slightly more ...


5

I don't think there is any faster way. You could come up with a script that copies the ownership info from a working installation, but writing the script would probably take more time than creating a new instance and starting from scratch.


1

The BSD install found on OpenBSD systems has this piece of code in it (from src/usr.bin/xinstall/xinstall.c): if (!S_ISREG(to_sb.st_mode)) errc(1, EFTYPE, "%s", to_name); This emits the error install: /dev/fd/4: Inappropriate file type or format when it's discovered that /dev/df/4 is not a regular file. (There's a separate earlier check for /dev/...


0

IMO, the best (easiest) way to do this is to when using dd, use a byte size (bs=) that can be evenly divided into your source file. This results in a whole number of block writes. Then you can reverse the process (read it back) ensuring the exact number of bytes are read by us both bs= and count= in the read command - and pipe it through the checksum program....


2

rename is expected to be atomic: it either completes fully or not at all. Renaming A to take the place of B is supposed to leave you with either both A and B intact (it didn't happen at all); or with only A's contents under the name B (it completed fully). As long as the system doesn't crash, that'll happen regardless of fsync (etc.) calls. If the system ...


2

The code is legal but "naive". The problem is exactly that of what happens during a crash There's a potential risk that the new data won't have space allocated to it before the directory updates, and so runs the risk of a data loss. A good app will call fflush() and fsync() to ensure the data is flushed to disk. The auto_da_alloc routines are an ...


0

If is perfectly legal, it will work, but it will not do what you want. The 2nd is obvious. It destroys the original before saving the new. The 1st is less obvious, it looks like if there was a system fail (e.g. power outage), then you would ether have done nothing (not started); have 2 files: old and new; or succeeded. However this is not the case, unless ...


3

stat(1) can show many file associated attributes by specifying special format strings to it's -c option. In your case, use stat -c '%a' ~/.ssh/authorized_keys to receive the same file mode in octal, 600. See it's manual page for a full list of supported format modifiers.


2

With zsh: print -rl ./**/results.out(.e_'grep -q string $REPLY'_:h) this searches recursively for regular files (.) named results.out, runs grep -q ... on each of them and if that evaluates true it prints only the head of the path (the path without the last element). Another way with find and sh, using parameter expansion to extract the head: find . -...


4

In a word, "no" :-) Linux tar will not stop any other process from reading the files while it is running. If you are concerned about writing the tar doesn't block that either, but if a file changes while tar is reading it then you'll get a warning message; if the directory structure changes while tar is in the middle of it then you might see some oddities ...


4

If you have GNU find, you can print the path using the %h format specifier %h Leading directories of file's name (all but the last ele‐ ment). If the file name contains no slashes (since it is in the current directory) the %h specifier expands to ".". So for example you could do find . -name 'results.out' -...


1

for i in $(find . -type f -name "results.out); do grep -l "string1" $i ; exitcode=${?} if [ ${exitcode} -eq 0 ] # string1 is found in file $i then path=${i%/*} echo ${path} fi done


0

Assuming I understood correctly you want to do just that: find . -type f -name "results.out" -exec grep -l "string1" {} \; | xargs dirname First part gets matching filenames, then xargs passes those as an argument to dirname program which 'strips' filelame from path


0

The answers to your questions: If the SystemOut.log file is owned by the same or more privileged account that runs the script, yes you can write to it, but I suggest not doing this, as you may need to provide that log to vendor for troubleshooting a problem one day and foreign entries in the log may throw them off and at the worst case they might refuse to ...


0

For a 2 column output format with "dirName numFiles", where "dirName" is one of "/ /bin /usr /usr/sbin" "numFiles is the count of files in above directory being >100K You could also use : $ for i in / /bin /usr /usr/bin; do echo -en "$i " ; find $i -maxdepth 1 -size +100k | wc -l; done | column -t Example output: / 0 /bin 46 /usr ...


1

With GNU find: find . -name '*.log' -printf '%p,%s\n' That will print the filename and the file's size in bytes, separated by a comma. Use %f instead of %p if you only want the file's basename (i.e. without the path). To display as kilobytes (units of 10^3, "KB") or kibibytes (units of 2^10, "KiB"), you'll need to post-process the output. See A ...


1

find . type -f ! -name '*.jpeg' ! -name '*.csv' -delete Read this as: traverse the current directory; when you find a file that is a regular file, and whose name does not match *.jpeg, and whose name is does not match *.csv, then delete it. If your version of find doesn't have -delete, make find invoke the rm command: replacte -delete by -exec rm {} +. ...


1

It seems that your file was created using superuser sudo (root/admin) attributes so, in order to modify o delete this file you would need to authenticate as a sudo, to do this simply type: sudo rm -rf path/to/file here rm -rf stands as remove recursively so that if path/to/file is a folder all its content will be removed. Your machine will ask you for ...


0

You could try to delete the folder with sudo. sudo rm -rf foldername


7

If you only want to delete a file in /home/charlesingalls (and not a file in a subdirectory) then it's easy: just check that the argument doesn't contain a /. case "$1" in */*) echo 1>&2 "Refusing to remove a file in another directory"; exit 2;; *) rm -f /home/charlesingalls/"$1";; esac This runs rm even if the argument is . or .. or empty, but ...


2

What you are suggesting is nigh impossible to do properly with standard tools. As you noticed, saving the command history is usual will not work, since the file will be owned by the user, and they can can delete, clear or edit the file at will. Even if we could work around this, perhaps by making the command history file a pipe read by some trusted process, ...


-1

ls -l will give you the all the data you need and more: : ls -l /var/log/*.log ... -rw-r--r-- 1 root root 123456 Jul 11 17:28 /var/log/xinetd.log ... Then you can extract the fields you need using awk: : ls -l /var/log/*.log | awk '{print $5,$9}' 123456 /var/log/xinetd.log If you want it separated with some other char: ...


0

This might help: ls -l --block-size=K *.log | awk {'print $9","$5'} > nameSize.csv


0

This would be my best guess and then put the contents in a file in your home directory called var-log.csv find . -type f -name "*.log" -exec ls -s {} \; > ~/var-log.csv


2

The pcregrep utility supports matching for multi-line patterns, so this is easy. First, you need a list of files to search within; in a git repository, my own git find utility can be useful for this, but regular find(1) and other tools will also do. Pass the list of files to pcregrep, dump its output into a temporary file, then hand-review the file list (e....


0

It's difficult to give a good answer without knowing more about your setup, but it sounds like a way to achieve some of your goals, assuming you use a file system that supports it, such as ext3, would be to mark the log file "append-only", using chattr +a <file>. Setting or unsetting the attribute requires special privileges, and then the file can ...


3

With zsh: setopt extendedglob # best in ~/.zshrc ls -ld -- (#ia1)hello # case-insensitive, allow one error ls -ld -- (#ia2)hello # case-insensitive, allow up to two errors. Recursively, search hidden files (and in hidden dirs) as well ((D)): ls -ld -- /**/(#ia2)hello(D) (note that it doesn't do any sorting by similarity, only ls's sorting by name of ...


1

It is certainly possible, although not popular. I've never really used the tool, but I know what too look for; you might want to try fzf. Generally, what you want is so called "fuzzy search", name derived from fuzzy logic. You know more or less what you want. The more or less part makes it fuzzy. I would give fzf a try if I were you, but consider other ...


2

If you want to forbid paths completely, the simplest way is to test if the variable contains a slash (/). In bash: if [[ "$1" = */* ]] ; then... This will block all paths, though, including foo/bar. You could test for .. instead, but that would leave the possibility of symlinks pointing to directories outside the target path. If you only want to allow ...


10

This answer assumes that $1 is allowed to include subdirectories. If you are interested in the simpler case where $1 should be a simple directory name, then see one of the other answers. Wildcards are not expanded when in double-quotes. Since $1 is in double-quotes, wildcards are not a problem. Both ../ and symlinks can obscure the real location of a ...


7

The basic idea is that you can't access files outside the document root. That's the point of the document root. There are several protections that prevent Apache from following symlinks outside the root. You need to enable FollowSymlinks in the directory containing the link, but if you can browse the files, it means this is already done. You also need to ...


2

lsof is the right tool for this job, but by default it examines all PIDs so it's slow and CPU intensive. Fortunately, there are some ways to speed it up. BTW, virt-manager won't be the process keeping the VM's disk image-file/device open. That'll be one of the qemu binaries, e.g. qemu-system-x86_64   If you know for a fact that only specific ...


6

On Linux with the inotify tools installed, you could do: #! /bin/zsh - file=${1?} # if it's a symlink, we want the real file, readlink also tells us # if the file is accessible file=$(readlink -e -- "$file") || exit # start inotifywait as a coproc so we can terminate it after we're # done: coproc LC_ALL=C inotifywait -me close --format . -- "$file" 2>&...


4

The lsof command can tell you if a file is in use. You can put that in a while loop with a sleep to make it check every so often. For example: In window 1 you can run sleep 10000 > /tmp/x In window 2 run this script: #!/bin/bash FILE=/tmp/x while [ -n "$(lsof "$FILE")" ] do sleep 1 done echo "File $FILE not in use" Now when you press control-C ...


4

The only way is to have a directory that the user can't write to. Create a single file in that directory and give them permission to write that file. They won't be able to remove the file nor to create another file. They won't be able to rename the file either. But they can overwrite the file, and they can change the file's metadata (timestamps, permissions, ...


2

When you pass an argument beginning with a dash to a command, and you don't want this argument to be interpreted as an option, pass -- (double dash) as an argument first. With almost all commands, -- means “no more options after this”. rename.ul -- '-' '' -* Another possibility is to arrange for the argument not to start with a dash. This isn't always ...


4

for f in -*.mp3; do echo mv -- "$f" "${f:1}" done When you are sure that it does what you want it to do, remove the echo. The double dash (--) is necessary to stop mv from interpreting the - in the filenames as an option. Quoting the variables is necessary for the cases where the filenames contains spaces.


0

In this case , root has permission to write to the directory, so root's editor writes a file /path/file.tmp (or some similar name) then moves the new file to /path/file. Since root just created the file, it is owned by root. This is how some of the editors work by default. For more help about editors and preserving file permissions etc , see the link below: ...


1

Combining seq mentioned by @123 in a comment and a few seq examples the help of "echo without newline" (Stack Overflow) knowing that I need busybox I found the following works best for my needs: for i in $(busybox seq 10); do echo -n "1" >> filename; done where 10 defines the number of items to write.


4

For an unlimited amount of arbitrary data, don't forget about yes! $ yes 42 42 42 42 42 42 42 42 42 42 42 42 42 ^C Hit Control-C when you've had enough! Alternatively to Control-C, use timeout: timeout 10 yes 42


1

While loop http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html plus basic math $ a=1 $ a=$(($a+1)) $ echo $a 2


0

For those who wants a solution, here you go: the install command doesn't work recursivly. So I wrote a shell script that does the trick. The first argument is the folder you want to copy, and the second is the target directory #!/bin/sh # Program to use the command install recursivly in a folder magic_func() { echo "entering ${1}" echo "target $2"...


0

Source side of the install is files list (according to info). So, use install source/* /destination -d and -D options create missed directories in the destination (with difference), -t option means that destination is the directory. With directory option it copies each source file into destination folder with source's file name


2

If your files have EXIF data that includes the creation date and time, then you can use exiftool to list just the hour and filename, and filter on that: find . -name '*jpg' -exec exiftool -q -d '%H' -p '$CreateDate $filename' \; 2>/dev/null | awk '$1>=6 && $1<18 {$1=""; print}' Beware, check if the date/time in the files is in local time ...


2

this command worked for me find . -iname "*pg" -printf '%Tc %p\n' | grep "\ 08:\|\ 07:\| \06:" it is nonetheless the files' unix timestamps not the exif data timestamp which is used for the search and I am unsure about performance, but I gave this answer as you indicated findutils as a tag


6

A straightforward combination of mkdir -p and mv should be enough for f in *; do d="${f:0:2}"; mkdir -p "$d"; mv -t "$d" -- "$f"; done Demonstrating: $ ls 0dckGYH5.jpg 32_17pxH.png 32Pz5-WQ.png Hsf4BQW9.jpg xh-fa3Nu.gif zYtBEaKA.png $ for f in *; do d="${f:0:2}"; mkdir -p "$d"; mv -t "$d" -- "$f"; done $ tree . . ├── 0d │   └── 0dckGYH5.jpg ├── 32 ...


2

another option is AIDE (advanced intrusion detection environment). It is free and you can get started pretty easy with one of the sample config files.


2

You have the linux audit system for that, I don't know if it's installed by default on debian but you ca install it by: $ sudo apt-get install auditd audispd-plugins From there you need to configure it, the configuration file is /etc/audit/audit.rules, a rule for your purpose would be like: # Delete all previous rules -D # Set buffer size -b 8192 # ...



Top 50 recent answers are included