Home > Mobile >  style for writing many long lines in bash all with a common start
style for writing many long lines in bash all with a common start

Time:12-16

Consider a Bash script having roughly the following form:

some long command here then parts that are different
some long command here but the second part is not the same
some long command here and another part that is different

As seen, the first part of each statement (some long command here) is redundant.

One way to eliminate the redundancy might be the following:

while read words; do some long command here $words; done <<EOF
then parts that are different
but the second part is not the same
and another part that is different
EOF

This solution is rather inelegant, but a larger problem is that it is not correct if a line should take form as follows:

some long command here and then "a quoted string that is a single argument"

A final solution is to place the redundant part in a function, demonstrated as follows:

base_cmd() {
  some long string here $@
}
base_cmd then parts that are different
base_cmd but the second part is not the same
base_cmd and another part that is different
base_cmd and then "a quoted string that is a single argument"

This form is awkward too, as it either places function definitions in the code body, or requires a separation of the parts of the command into separate sections of the script.

What is a solution more elegant than the ones already suggested?

CodePudding user response:

A function is the most elegant. It is portable. Your function does not preserve the quoted string.

base_cmd() {
  some long string here "$@"
}
base_cmd then parts that are different
base_cmd but the second part is not the same
base_cmd and another part that is different
base_cmd and then "a quoted string that is a single argument"

An array is on the second place. And is specific to bash and requires a lot of shift typing and is harder to refactor:

base_cmd=(some long string here)
"${base_cmd[@]}" then parts that are different
"${base_cmd[@]}" but the second part is not the same
"${base_cmd[@]}" and another part that is different
"${base_cmd[@]}" and then "a quoted string that is a single argument"

Then, there's a normal variable and depending on word-splitting on the third place. So base_cmd set can't contain spaces.

CodePudding user response:

Use an array to store words and printf the array like this:

#!/usr/bin/env bash

words=(
  'then parts that are different'
  'but the second part is not the same'
  'and another part that is different'
)

printf 'some long string here %s\n' "${words[@]}"

Now with running your own command:

#!/usr/bin/env bash

# Dummy just prints self with all its arguments
some() {
  printf 'some %s\n' "$*"
}

common_args=( long string here )

while read -ra diff_args; do
  some "${common_args[@]}" "${diff_args[@]}"
done <<EOF
then parts that are different
but the second part is not the same
and another part that is different
EOF
  • Related