简体   繁体   中英

Run find command from a bash file

Hi people: I'm making a xfe script to take a given directory as source file, use zenity to get output dir and perform some operations, for example:

#!/bin/bash

OUTPUT_DIR=`zenity --file-selection --directory --filename="$1"`

if [ $? == 0 ]; then
    find . -maxdepth 1 -type f -name "*.wav" -exec bash -c 'oggenc -Q "$0" -q 3 "$OUTPUT_DIR/${0%.wav}.ogg"' {} \;
fi

When the script is invoked, oggenc is not executed...any ideas?

Solution : Based on answers bellow, this works as expected:

#!/usr/bin/sh

OUTPUT_DIR=$(zenity --file-selection --directory --filename="$1")

if [ $? = 0 ]; then
    export OUTPUT_DIR
    find "$1" -maxdepth 1 -type f -name "*.wav" -exec sh -c 'oggenc -Q "$0" -q 3 -o "${OUTPUT_DIR}/$(basename "${0/.wav/.ogg}")"' {} \;
fi
zenity --info --text="Done"

To make the variable $OUTPUT_DIR available to the child process, add one line:

OUTPUT_DIR=$(zenity --file-selection --directory --filename="$1")
if [ $? = 0 ]; then
    export OUTPUT_DIR
    find . -maxdepth 1 -type f -name "*.wav" -exec bash -c 'oggenc -Q "$0" -q 3 "$OUTPUT_DIR/${0%.wav}.ogg"' {} \;
fi

Or, slightly simpler:

if OUTPUT_DIR=$(zenity --file-selection --directory --filename="$1"); then
    export OUTPUT_DIR
    find . -maxdepth 1 -type f -name "*.wav" -exec bash -c 'oggenc -Q "$0" -q 3 "$OUTPUT_DIR/${0%.wav}.ogg"' {} \;
fi

Notes:

  1. The command 'oggenc -Q "$0" -q 3 "$OUTPUT_DIR/${0%.wav}.ogg"' appears in single-quotes. This means that the variables are not expanded by the parent shell. They are expanded by the child shell. To make it available to the child shell, a variable must be exported.

  2. [ $? == 0 ] [ $? == 0 ] works in bash but [ $? = 0 ] [ $? = 0 ] will also work and is more portable.

  3. Command substitution can be done with backticks and some old shells only accept backticks. For modern shells, however, the $(...) has the advantage of improved readability (some fonts don't clearly distinguish back and normal quotes). Also $(...) can be nested in a clear and sensible way.

I'd prefer to use while loop over pipelining. Your code may be rewritten in this way

while IFS= read -r -d '' file; do 
   oggenc -Q "${file}" -q 3 "${OUTPUT_DIR}/$(basename ${file/.wav/.ogg})"
done < <(find . -maxdepth 1 -type f -name "*.wav" -print0)

The reason why your code was not working is that single quotes ' forbids variables expansion so $OUTPUT_DIR will not expand.

EDIT

-print0 is used in conjunction with IFS= is to split find output only on \\0 but not on whitespace in filenames.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM