Execute command (function) from a variable in a script












1















So, I want to create a script where I check sth from a website. I have a text file with different websites in it and I want to check all websites simultaneously. To do this I'm creating a command step by step in a variable calling a function which will check every website. This is my code:



checkWebsite(){
WEBSITE="$2"
echo "Parameter is $WEBSITE"
}

COUNTER=0;

input=websites.txt

myCommand=()
while IFS= read -r line
do
if [[ "$line" != "#"* ]]; #ignoring comments if there are any
then
myCommand[COUNTER]="checkWebsite $line"
COUNTER=$((COUNTER + 1))
myCommand[COUNTER]=" & "
COUNTER=$((COUNTER + 1))
fi
done < "$input"

unset 'myCommand[${#myCommand[@]}-1]' #deleting the last " & "

echo "MY COMMAND: "
echo ${myCommand[@]}
echo " "

echo ${myCommand[0]}
checkWebsite ${myCommand[0]}
"${myCommand[0]}"


These are the results:
results



As you can see, if I call the function from the script everything is ok but if I call the function from the variable it doesn't work. I understand why this is happening(it's like I run that command from the terminal) but I don't know how can I make it run the function from the script when I execute the command from the variable. Does anyone know how can I make that happen?



Thanks in advance










share|improve this question

























  • Putting it in a variable makes it harder and messier than it has to be. Is there a reason why you're not just running it directly?

    – that other guy
    Nov 24 '18 at 20:08











  • Asked and answered a lot of times: bash command parameter substitution site:stackoverflow.com. Which would you like as your duplicate?

    – jww
    Nov 24 '18 at 20:17











  • Also see BashFAQ #50. "${myCommand[0]}" entirely defeats the whole purpose of using an array -- dereffing just the first element means it's just another string.

    – Charles Duffy
    Nov 24 '18 at 20:19











  • BTW, declare -p myCommand gives you a much more accurate idea of your array's contents than echo ${myCommand[@]} does. (For that matter, printf '%qn' "${myCommand[@]}" would be an improvement as well).

    – Charles Duffy
    Nov 25 '18 at 0:39
















1















So, I want to create a script where I check sth from a website. I have a text file with different websites in it and I want to check all websites simultaneously. To do this I'm creating a command step by step in a variable calling a function which will check every website. This is my code:



checkWebsite(){
WEBSITE="$2"
echo "Parameter is $WEBSITE"
}

COUNTER=0;

input=websites.txt

myCommand=()
while IFS= read -r line
do
if [[ "$line" != "#"* ]]; #ignoring comments if there are any
then
myCommand[COUNTER]="checkWebsite $line"
COUNTER=$((COUNTER + 1))
myCommand[COUNTER]=" & "
COUNTER=$((COUNTER + 1))
fi
done < "$input"

unset 'myCommand[${#myCommand[@]}-1]' #deleting the last " & "

echo "MY COMMAND: "
echo ${myCommand[@]}
echo " "

echo ${myCommand[0]}
checkWebsite ${myCommand[0]}
"${myCommand[0]}"


These are the results:
results



As you can see, if I call the function from the script everything is ok but if I call the function from the variable it doesn't work. I understand why this is happening(it's like I run that command from the terminal) but I don't know how can I make it run the function from the script when I execute the command from the variable. Does anyone know how can I make that happen?



Thanks in advance










share|improve this question

























  • Putting it in a variable makes it harder and messier than it has to be. Is there a reason why you're not just running it directly?

    – that other guy
    Nov 24 '18 at 20:08











  • Asked and answered a lot of times: bash command parameter substitution site:stackoverflow.com. Which would you like as your duplicate?

    – jww
    Nov 24 '18 at 20:17











  • Also see BashFAQ #50. "${myCommand[0]}" entirely defeats the whole purpose of using an array -- dereffing just the first element means it's just another string.

    – Charles Duffy
    Nov 24 '18 at 20:19











  • BTW, declare -p myCommand gives you a much more accurate idea of your array's contents than echo ${myCommand[@]} does. (For that matter, printf '%qn' "${myCommand[@]}" would be an improvement as well).

    – Charles Duffy
    Nov 25 '18 at 0:39














1












1








1








So, I want to create a script where I check sth from a website. I have a text file with different websites in it and I want to check all websites simultaneously. To do this I'm creating a command step by step in a variable calling a function which will check every website. This is my code:



checkWebsite(){
WEBSITE="$2"
echo "Parameter is $WEBSITE"
}

COUNTER=0;

input=websites.txt

myCommand=()
while IFS= read -r line
do
if [[ "$line" != "#"* ]]; #ignoring comments if there are any
then
myCommand[COUNTER]="checkWebsite $line"
COUNTER=$((COUNTER + 1))
myCommand[COUNTER]=" & "
COUNTER=$((COUNTER + 1))
fi
done < "$input"

unset 'myCommand[${#myCommand[@]}-1]' #deleting the last " & "

echo "MY COMMAND: "
echo ${myCommand[@]}
echo " "

echo ${myCommand[0]}
checkWebsite ${myCommand[0]}
"${myCommand[0]}"


These are the results:
results



As you can see, if I call the function from the script everything is ok but if I call the function from the variable it doesn't work. I understand why this is happening(it's like I run that command from the terminal) but I don't know how can I make it run the function from the script when I execute the command from the variable. Does anyone know how can I make that happen?



Thanks in advance










share|improve this question
















So, I want to create a script where I check sth from a website. I have a text file with different websites in it and I want to check all websites simultaneously. To do this I'm creating a command step by step in a variable calling a function which will check every website. This is my code:



checkWebsite(){
WEBSITE="$2"
echo "Parameter is $WEBSITE"
}

COUNTER=0;

input=websites.txt

myCommand=()
while IFS= read -r line
do
if [[ "$line" != "#"* ]]; #ignoring comments if there are any
then
myCommand[COUNTER]="checkWebsite $line"
COUNTER=$((COUNTER + 1))
myCommand[COUNTER]=" & "
COUNTER=$((COUNTER + 1))
fi
done < "$input"

unset 'myCommand[${#myCommand[@]}-1]' #deleting the last " & "

echo "MY COMMAND: "
echo ${myCommand[@]}
echo " "

echo ${myCommand[0]}
checkWebsite ${myCommand[0]}
"${myCommand[0]}"


These are the results:
results



As you can see, if I call the function from the script everything is ok but if I call the function from the variable it doesn't work. I understand why this is happening(it's like I run that command from the terminal) but I don't know how can I make it run the function from the script when I execute the command from the variable. Does anyone know how can I make that happen?



Thanks in advance







linux bash shell terminal sh






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 20:15









jww

52.8k39224492




52.8k39224492










asked Nov 24 '18 at 19:35









Savvas ThSavvas Th

154




154













  • Putting it in a variable makes it harder and messier than it has to be. Is there a reason why you're not just running it directly?

    – that other guy
    Nov 24 '18 at 20:08











  • Asked and answered a lot of times: bash command parameter substitution site:stackoverflow.com. Which would you like as your duplicate?

    – jww
    Nov 24 '18 at 20:17











  • Also see BashFAQ #50. "${myCommand[0]}" entirely defeats the whole purpose of using an array -- dereffing just the first element means it's just another string.

    – Charles Duffy
    Nov 24 '18 at 20:19











  • BTW, declare -p myCommand gives you a much more accurate idea of your array's contents than echo ${myCommand[@]} does. (For that matter, printf '%qn' "${myCommand[@]}" would be an improvement as well).

    – Charles Duffy
    Nov 25 '18 at 0:39



















  • Putting it in a variable makes it harder and messier than it has to be. Is there a reason why you're not just running it directly?

    – that other guy
    Nov 24 '18 at 20:08











  • Asked and answered a lot of times: bash command parameter substitution site:stackoverflow.com. Which would you like as your duplicate?

    – jww
    Nov 24 '18 at 20:17











  • Also see BashFAQ #50. "${myCommand[0]}" entirely defeats the whole purpose of using an array -- dereffing just the first element means it's just another string.

    – Charles Duffy
    Nov 24 '18 at 20:19











  • BTW, declare -p myCommand gives you a much more accurate idea of your array's contents than echo ${myCommand[@]} does. (For that matter, printf '%qn' "${myCommand[@]}" would be an improvement as well).

    – Charles Duffy
    Nov 25 '18 at 0:39

















Putting it in a variable makes it harder and messier than it has to be. Is there a reason why you're not just running it directly?

– that other guy
Nov 24 '18 at 20:08





Putting it in a variable makes it harder and messier than it has to be. Is there a reason why you're not just running it directly?

– that other guy
Nov 24 '18 at 20:08













Asked and answered a lot of times: bash command parameter substitution site:stackoverflow.com. Which would you like as your duplicate?

– jww
Nov 24 '18 at 20:17





Asked and answered a lot of times: bash command parameter substitution site:stackoverflow.com. Which would you like as your duplicate?

– jww
Nov 24 '18 at 20:17













Also see BashFAQ #50. "${myCommand[0]}" entirely defeats the whole purpose of using an array -- dereffing just the first element means it's just another string.

– Charles Duffy
Nov 24 '18 at 20:19





Also see BashFAQ #50. "${myCommand[0]}" entirely defeats the whole purpose of using an array -- dereffing just the first element means it's just another string.

– Charles Duffy
Nov 24 '18 at 20:19













BTW, declare -p myCommand gives you a much more accurate idea of your array's contents than echo ${myCommand[@]} does. (For that matter, printf '%qn' "${myCommand[@]}" would be an improvement as well).

– Charles Duffy
Nov 25 '18 at 0:39





BTW, declare -p myCommand gives you a much more accurate idea of your array's contents than echo ${myCommand[@]} does. (For that matter, printf '%qn' "${myCommand[@]}" would be an improvement as well).

– Charles Duffy
Nov 25 '18 at 0:39












1 Answer
1






active

oldest

votes


















3














Don't use an array here. It causes a lot of trouble and adds no value whatsoever. Instead, start your background tasks inside the loop:



while IFS= read -r line; do
[[ "$line" = "#"* ]] || checkWebsite "$line" &
done < "$input"




If you really want an array, populate it from the loop, and -- again -- start items individually without it.



websites=( )
while IFS= read -r line; do
[[ "$line" = "#"* ]] || websites+=( "$line" )
done < "$input"

for site in "${websites[@]}"; do
checkWebsite "$site" &
done




Why doesn't the other approach work? Because & only acts as a command separator when parsed as syntax, and parameter expansion results are data, not syntax.



You would need to use eval to make your expansion results parse as syntax; unless done with great care, this would cause serious security vulnerabilities.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53461708%2fexecute-command-function-from-a-variable-in-a-script%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    Don't use an array here. It causes a lot of trouble and adds no value whatsoever. Instead, start your background tasks inside the loop:



    while IFS= read -r line; do
    [[ "$line" = "#"* ]] || checkWebsite "$line" &
    done < "$input"




    If you really want an array, populate it from the loop, and -- again -- start items individually without it.



    websites=( )
    while IFS= read -r line; do
    [[ "$line" = "#"* ]] || websites+=( "$line" )
    done < "$input"

    for site in "${websites[@]}"; do
    checkWebsite "$site" &
    done




    Why doesn't the other approach work? Because & only acts as a command separator when parsed as syntax, and parameter expansion results are data, not syntax.



    You would need to use eval to make your expansion results parse as syntax; unless done with great care, this would cause serious security vulnerabilities.






    share|improve this answer




























      3














      Don't use an array here. It causes a lot of trouble and adds no value whatsoever. Instead, start your background tasks inside the loop:



      while IFS= read -r line; do
      [[ "$line" = "#"* ]] || checkWebsite "$line" &
      done < "$input"




      If you really want an array, populate it from the loop, and -- again -- start items individually without it.



      websites=( )
      while IFS= read -r line; do
      [[ "$line" = "#"* ]] || websites+=( "$line" )
      done < "$input"

      for site in "${websites[@]}"; do
      checkWebsite "$site" &
      done




      Why doesn't the other approach work? Because & only acts as a command separator when parsed as syntax, and parameter expansion results are data, not syntax.



      You would need to use eval to make your expansion results parse as syntax; unless done with great care, this would cause serious security vulnerabilities.






      share|improve this answer


























        3












        3








        3







        Don't use an array here. It causes a lot of trouble and adds no value whatsoever. Instead, start your background tasks inside the loop:



        while IFS= read -r line; do
        [[ "$line" = "#"* ]] || checkWebsite "$line" &
        done < "$input"




        If you really want an array, populate it from the loop, and -- again -- start items individually without it.



        websites=( )
        while IFS= read -r line; do
        [[ "$line" = "#"* ]] || websites+=( "$line" )
        done < "$input"

        for site in "${websites[@]}"; do
        checkWebsite "$site" &
        done




        Why doesn't the other approach work? Because & only acts as a command separator when parsed as syntax, and parameter expansion results are data, not syntax.



        You would need to use eval to make your expansion results parse as syntax; unless done with great care, this would cause serious security vulnerabilities.






        share|improve this answer













        Don't use an array here. It causes a lot of trouble and adds no value whatsoever. Instead, start your background tasks inside the loop:



        while IFS= read -r line; do
        [[ "$line" = "#"* ]] || checkWebsite "$line" &
        done < "$input"




        If you really want an array, populate it from the loop, and -- again -- start items individually without it.



        websites=( )
        while IFS= read -r line; do
        [[ "$line" = "#"* ]] || websites+=( "$line" )
        done < "$input"

        for site in "${websites[@]}"; do
        checkWebsite "$site" &
        done




        Why doesn't the other approach work? Because & only acts as a command separator when parsed as syntax, and parameter expansion results are data, not syntax.



        You would need to use eval to make your expansion results parse as syntax; unless done with great care, this would cause serious security vulnerabilities.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 24 '18 at 20:21









        Charles DuffyCharles Duffy

        174k25197252




        174k25197252






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53461708%2fexecute-command-function-from-a-variable-in-a-script%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)