1

I am trying to write a script on a Debian Jessie host.

I am having an issue with trying to run the following command (with a twist) in a script:

find ~/* -path ~/FileSniper* \ -prune -o \ -type f \( -name "*.mp4" -o -name "*.sh" -or -name "*.mp3" \) \ ! -name '*.txt' -printf "%f\n" 

What I am trying to do in the script is make the user have to type in the file formats he/she wants to search for, after that, I pipe this to sed, which will make sure it obtains the right format:

 echo "Input the formats like this: \"mp3,mp4,exe,sh\"" read -p "input:" formats formattedformats=`echo "-name \"*.""$formats""\"" | sed 's/,/" -o -name "*./g'` find_parameters=(\(formattedformats\)) 

Here the $find_parameters will contain something like:

-name "*.mp3" -o -name "*.mp4" -o -name "*.sh" 

I can't figure out what is wrong with this line:

find ~/* -path ~/FileSniper* -prune -o -type f "${find_parameters[@]}" ! -name "*.txt" -printf "%f\n" > foundfiles.txt 

I have researched what I could, but still haven't been able to figure out what is wrong. Please point me in the right direction.

3
  • If 'users' are running this script, -path ~/FileSniper* refers to their home directory. Also, try putting the full path to find instead of find like: /usr/bin/find also you are echoing to a file without putting the full path to the file. Try fixing all the relative path issues and possible $PATH issues and see if that fixes it. Once you have done these fixes, and if it still doesn't work, it might be easier to debug it. Commented Nov 9, 2015 at 2:45
  • is there a reason for ~/* ? are you trying to exclude hidden . directories? you could do find ~ -not -path '*/.*' ... instead. Commented Nov 9, 2015 at 2:56
  • i would also advise taking the input as command-line arguments rather than prompting and reading stdin - that way it's easier to re-use your script from other scripts just by calling it as, e.g., scriptname.sh mp3 mp4 exe sh Commented Nov 9, 2015 at 3:05

2 Answers 2

1

Here's a script that reads the file extensions from the command line (rather than from stdin) and uses them to build a regular expression to use with find's -iregex option.

It excludes hidden . directories and ~/FileSniper* as in your original example.

#! /bin/bash regexp='' for ext in "$@" ; do [ -n "$regexp" ] && regexp="$regexp\|" regexp="$regexp.*\.$ext$" done find ~ -not -path '*/.*' -not -path '*/FileSniper*' -type f \ -iregex "$regexp" > foundfiles.txt 
1

If your script is a #!/bin/sh type or is otherwise just .sh then it would explain why your ${find_parameters[@]} doesn't work on a Debian system which uses a default dash shell interpreter that doesn't implement the ${array[@]} type name extension.

I can also see how your -path ~/FileSniper* argument might come off with unwanted results - and the same goes for ~/* for that matter. As written those are shell expansions - not find expansions. The find [ ...paths... ] operands never expand and so ~/* - if that's really what you want - is as correct as it might be, but -path ~/FileSniper* is expanded to whatever the results might be by the parent shell before it is used as a pattern by find. And so if it doesn't match a ~/ path it is a moot point because * will remain as is anyway, but if it does then it no longer works as the pattern you intend.

You should quote it, probably: find ... -path ~/FileSniper\* unless you mean to look for a literal ~ tilde, in which case you should quote that, too.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.