makefile hangs when calling shell command head





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I want to print the first line of some text file from within my makefile.
Here's what I have, and it doesn't seem to work:



$ cat makefile
BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
all:
var=${MYDIR}/m.txt
@echo $(shell head -n 1 ${var})
# @echo $(shell head -n 1 ${MYDIR}/m.txt)


When I try to use make it simply hangs and I have to kill it.
When I remove the comment and use the head command directly on ${MYDIR}/m.txt everything works fine. What am I doing wrong here? Thanks!










share|improve this question























  • Tangentially, don't use @ to silence make, especially while debugging. Once you know exactly what's going on, you probably want to use make -s if you don't want to see what's happening.

    – tripleee
    Jan 3 at 12:55











  • I prefer this method of dealing with recipe echoing: make.mad-scientist.net/managing-recipe-echoing

    – MadScientist
    Jan 3 at 14:53


















1















I want to print the first line of some text file from within my makefile.
Here's what I have, and it doesn't seem to work:



$ cat makefile
BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
all:
var=${MYDIR}/m.txt
@echo $(shell head -n 1 ${var})
# @echo $(shell head -n 1 ${MYDIR}/m.txt)


When I try to use make it simply hangs and I have to kill it.
When I remove the comment and use the head command directly on ${MYDIR}/m.txt everything works fine. What am I doing wrong here? Thanks!










share|improve this question























  • Tangentially, don't use @ to silence make, especially while debugging. Once you know exactly what's going on, you probably want to use make -s if you don't want to see what's happening.

    – tripleee
    Jan 3 at 12:55











  • I prefer this method of dealing with recipe echoing: make.mad-scientist.net/managing-recipe-echoing

    – MadScientist
    Jan 3 at 14:53














1












1








1








I want to print the first line of some text file from within my makefile.
Here's what I have, and it doesn't seem to work:



$ cat makefile
BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
all:
var=${MYDIR}/m.txt
@echo $(shell head -n 1 ${var})
# @echo $(shell head -n 1 ${MYDIR}/m.txt)


When I try to use make it simply hangs and I have to kill it.
When I remove the comment and use the head command directly on ${MYDIR}/m.txt everything works fine. What am I doing wrong here? Thanks!










share|improve this question














I want to print the first line of some text file from within my makefile.
Here's what I have, and it doesn't seem to work:



$ cat makefile
BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
all:
var=${MYDIR}/m.txt
@echo $(shell head -n 1 ${var})
# @echo $(shell head -n 1 ${MYDIR}/m.txt)


When I try to use make it simply hangs and I have to kill it.
When I remove the comment and use the head command directly on ${MYDIR}/m.txt everything works fine. What am I doing wrong here? Thanks!







bash makefile






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 3 at 12:00









OrenIshShalomOrenIshShalom

1,158924




1,158924













  • Tangentially, don't use @ to silence make, especially while debugging. Once you know exactly what's going on, you probably want to use make -s if you don't want to see what's happening.

    – tripleee
    Jan 3 at 12:55











  • I prefer this method of dealing with recipe echoing: make.mad-scientist.net/managing-recipe-echoing

    – MadScientist
    Jan 3 at 14:53



















  • Tangentially, don't use @ to silence make, especially while debugging. Once you know exactly what's going on, you probably want to use make -s if you don't want to see what's happening.

    – tripleee
    Jan 3 at 12:55











  • I prefer this method of dealing with recipe echoing: make.mad-scientist.net/managing-recipe-echoing

    – MadScientist
    Jan 3 at 14:53

















Tangentially, don't use @ to silence make, especially while debugging. Once you know exactly what's going on, you probably want to use make -s if you don't want to see what's happening.

– tripleee
Jan 3 at 12:55





Tangentially, don't use @ to silence make, especially while debugging. Once you know exactly what's going on, you probably want to use make -s if you don't want to see what's happening.

– tripleee
Jan 3 at 12:55













I prefer this method of dealing with recipe echoing: make.mad-scientist.net/managing-recipe-echoing

– MadScientist
Jan 3 at 14:53





I prefer this method of dealing with recipe echoing: make.mad-scientist.net/managing-recipe-echoing

– MadScientist
Jan 3 at 14:53












2 Answers
2






active

oldest

votes


















4














Do not use the shell make function in recipes. Recipes are already shell scripts:



BASEDIR := $(HOME)/Downloads
MYDIR := $(BASEDIR)/ddd

all:
@var="$(MYDIR)/m.txt"; head -n 1 "$$var"


Notes:




  • Recipes are expanded by make before they are passed to the shell. This is where $(MYDIR) will be replaced by something like /home/doe/Downloads/ddd/m.txt. And this is why $var would not work. It would expand as ar, unless there is a make variable named v with a non-empty value FOO, in which case $var would expand as FOOar. $$var is expanded by make as $var, the shell syntax you want.


  • Each line of a recipe is executed by an independent shell. The following would thus not work:



    all:
    @var="$(MYDIR)/m.txt"
    @head -n 1 "$$var"


    because the shell variable assignment (var="/home/doe/Downloads/ddd/m.txt") and the shell variable expansion (head -n 1 "$var") would be executed by two different shells. If you want one single shell statement per line, use the line continuation:



    all:
    @var="$(MYDIR)/m.txt";
    head -n 1 "$$var"


    or:



    all:
    @var="$(MYDIR)/m.txt" &&
    head -n 1 "$$var"







share|improve this answer


























  • It is of course dubious whether putting the string in a variable and only using it once is any use at all, but I'll just leave this comment here. (^8

    – tripleee
    Jan 3 at 13:01






  • 1





    @tripleee: agreed. But I suspect the real Makefile will be different, at the end. So, let's show how to properly use shell variables in make recipes, it is always good to know.

    – Renaud Pacalet
    Jan 3 at 13:02













  • how come I can't extend the solution to: `x=$(head -n 1 "$$var"); echo $$x'

    – OrenIshShalom
    Jan 3 at 19:45








  • 1





    @OrenIshShalom: you can... if you properly escape all $ signs: x=$$(head -n 1 "$$var"); echo "$$x".

    – Renaud Pacalet
    Jan 4 at 0:48





















1














Don't use variable assignments in recipes. In your command head -n 1 ${var} the expression ${var} expands to nothing and hence head waits on standard input. The following makefile should work:



BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
var=${MYDIR}/m.txt
all:
@echo $(shell head -n 1 ${var})





share|improve this answer
























  • You still want to avoid using $(shell) in the recipe. The echo is also useless.

    – tripleee
    Jan 3 at 12:56














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%2f54021879%2fmakefile-hangs-when-calling-shell-command-head%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














Do not use the shell make function in recipes. Recipes are already shell scripts:



BASEDIR := $(HOME)/Downloads
MYDIR := $(BASEDIR)/ddd

all:
@var="$(MYDIR)/m.txt"; head -n 1 "$$var"


Notes:




  • Recipes are expanded by make before they are passed to the shell. This is where $(MYDIR) will be replaced by something like /home/doe/Downloads/ddd/m.txt. And this is why $var would not work. It would expand as ar, unless there is a make variable named v with a non-empty value FOO, in which case $var would expand as FOOar. $$var is expanded by make as $var, the shell syntax you want.


  • Each line of a recipe is executed by an independent shell. The following would thus not work:



    all:
    @var="$(MYDIR)/m.txt"
    @head -n 1 "$$var"


    because the shell variable assignment (var="/home/doe/Downloads/ddd/m.txt") and the shell variable expansion (head -n 1 "$var") would be executed by two different shells. If you want one single shell statement per line, use the line continuation:



    all:
    @var="$(MYDIR)/m.txt";
    head -n 1 "$$var"


    or:



    all:
    @var="$(MYDIR)/m.txt" &&
    head -n 1 "$$var"







share|improve this answer


























  • It is of course dubious whether putting the string in a variable and only using it once is any use at all, but I'll just leave this comment here. (^8

    – tripleee
    Jan 3 at 13:01






  • 1





    @tripleee: agreed. But I suspect the real Makefile will be different, at the end. So, let's show how to properly use shell variables in make recipes, it is always good to know.

    – Renaud Pacalet
    Jan 3 at 13:02













  • how come I can't extend the solution to: `x=$(head -n 1 "$$var"); echo $$x'

    – OrenIshShalom
    Jan 3 at 19:45








  • 1





    @OrenIshShalom: you can... if you properly escape all $ signs: x=$$(head -n 1 "$$var"); echo "$$x".

    – Renaud Pacalet
    Jan 4 at 0:48


















4














Do not use the shell make function in recipes. Recipes are already shell scripts:



BASEDIR := $(HOME)/Downloads
MYDIR := $(BASEDIR)/ddd

all:
@var="$(MYDIR)/m.txt"; head -n 1 "$$var"


Notes:




  • Recipes are expanded by make before they are passed to the shell. This is where $(MYDIR) will be replaced by something like /home/doe/Downloads/ddd/m.txt. And this is why $var would not work. It would expand as ar, unless there is a make variable named v with a non-empty value FOO, in which case $var would expand as FOOar. $$var is expanded by make as $var, the shell syntax you want.


  • Each line of a recipe is executed by an independent shell. The following would thus not work:



    all:
    @var="$(MYDIR)/m.txt"
    @head -n 1 "$$var"


    because the shell variable assignment (var="/home/doe/Downloads/ddd/m.txt") and the shell variable expansion (head -n 1 "$var") would be executed by two different shells. If you want one single shell statement per line, use the line continuation:



    all:
    @var="$(MYDIR)/m.txt";
    head -n 1 "$$var"


    or:



    all:
    @var="$(MYDIR)/m.txt" &&
    head -n 1 "$$var"







share|improve this answer


























  • It is of course dubious whether putting the string in a variable and only using it once is any use at all, but I'll just leave this comment here. (^8

    – tripleee
    Jan 3 at 13:01






  • 1





    @tripleee: agreed. But I suspect the real Makefile will be different, at the end. So, let's show how to properly use shell variables in make recipes, it is always good to know.

    – Renaud Pacalet
    Jan 3 at 13:02













  • how come I can't extend the solution to: `x=$(head -n 1 "$$var"); echo $$x'

    – OrenIshShalom
    Jan 3 at 19:45








  • 1





    @OrenIshShalom: you can... if you properly escape all $ signs: x=$$(head -n 1 "$$var"); echo "$$x".

    – Renaud Pacalet
    Jan 4 at 0:48
















4












4








4







Do not use the shell make function in recipes. Recipes are already shell scripts:



BASEDIR := $(HOME)/Downloads
MYDIR := $(BASEDIR)/ddd

all:
@var="$(MYDIR)/m.txt"; head -n 1 "$$var"


Notes:




  • Recipes are expanded by make before they are passed to the shell. This is where $(MYDIR) will be replaced by something like /home/doe/Downloads/ddd/m.txt. And this is why $var would not work. It would expand as ar, unless there is a make variable named v with a non-empty value FOO, in which case $var would expand as FOOar. $$var is expanded by make as $var, the shell syntax you want.


  • Each line of a recipe is executed by an independent shell. The following would thus not work:



    all:
    @var="$(MYDIR)/m.txt"
    @head -n 1 "$$var"


    because the shell variable assignment (var="/home/doe/Downloads/ddd/m.txt") and the shell variable expansion (head -n 1 "$var") would be executed by two different shells. If you want one single shell statement per line, use the line continuation:



    all:
    @var="$(MYDIR)/m.txt";
    head -n 1 "$$var"


    or:



    all:
    @var="$(MYDIR)/m.txt" &&
    head -n 1 "$$var"







share|improve this answer















Do not use the shell make function in recipes. Recipes are already shell scripts:



BASEDIR := $(HOME)/Downloads
MYDIR := $(BASEDIR)/ddd

all:
@var="$(MYDIR)/m.txt"; head -n 1 "$$var"


Notes:




  • Recipes are expanded by make before they are passed to the shell. This is where $(MYDIR) will be replaced by something like /home/doe/Downloads/ddd/m.txt. And this is why $var would not work. It would expand as ar, unless there is a make variable named v with a non-empty value FOO, in which case $var would expand as FOOar. $$var is expanded by make as $var, the shell syntax you want.


  • Each line of a recipe is executed by an independent shell. The following would thus not work:



    all:
    @var="$(MYDIR)/m.txt"
    @head -n 1 "$$var"


    because the shell variable assignment (var="/home/doe/Downloads/ddd/m.txt") and the shell variable expansion (head -n 1 "$var") would be executed by two different shells. If you want one single shell statement per line, use the line continuation:



    all:
    @var="$(MYDIR)/m.txt";
    head -n 1 "$$var"


    or:



    all:
    @var="$(MYDIR)/m.txt" &&
    head -n 1 "$$var"








share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 3 at 13:03

























answered Jan 3 at 12:48









Renaud PacaletRenaud Pacalet

9,69821732




9,69821732













  • It is of course dubious whether putting the string in a variable and only using it once is any use at all, but I'll just leave this comment here. (^8

    – tripleee
    Jan 3 at 13:01






  • 1





    @tripleee: agreed. But I suspect the real Makefile will be different, at the end. So, let's show how to properly use shell variables in make recipes, it is always good to know.

    – Renaud Pacalet
    Jan 3 at 13:02













  • how come I can't extend the solution to: `x=$(head -n 1 "$$var"); echo $$x'

    – OrenIshShalom
    Jan 3 at 19:45








  • 1





    @OrenIshShalom: you can... if you properly escape all $ signs: x=$$(head -n 1 "$$var"); echo "$$x".

    – Renaud Pacalet
    Jan 4 at 0:48





















  • It is of course dubious whether putting the string in a variable and only using it once is any use at all, but I'll just leave this comment here. (^8

    – tripleee
    Jan 3 at 13:01






  • 1





    @tripleee: agreed. But I suspect the real Makefile will be different, at the end. So, let's show how to properly use shell variables in make recipes, it is always good to know.

    – Renaud Pacalet
    Jan 3 at 13:02













  • how come I can't extend the solution to: `x=$(head -n 1 "$$var"); echo $$x'

    – OrenIshShalom
    Jan 3 at 19:45








  • 1





    @OrenIshShalom: you can... if you properly escape all $ signs: x=$$(head -n 1 "$$var"); echo "$$x".

    – Renaud Pacalet
    Jan 4 at 0:48



















It is of course dubious whether putting the string in a variable and only using it once is any use at all, but I'll just leave this comment here. (^8

– tripleee
Jan 3 at 13:01





It is of course dubious whether putting the string in a variable and only using it once is any use at all, but I'll just leave this comment here. (^8

– tripleee
Jan 3 at 13:01




1




1





@tripleee: agreed. But I suspect the real Makefile will be different, at the end. So, let's show how to properly use shell variables in make recipes, it is always good to know.

– Renaud Pacalet
Jan 3 at 13:02







@tripleee: agreed. But I suspect the real Makefile will be different, at the end. So, let's show how to properly use shell variables in make recipes, it is always good to know.

– Renaud Pacalet
Jan 3 at 13:02















how come I can't extend the solution to: `x=$(head -n 1 "$$var"); echo $$x'

– OrenIshShalom
Jan 3 at 19:45







how come I can't extend the solution to: `x=$(head -n 1 "$$var"); echo $$x'

– OrenIshShalom
Jan 3 at 19:45






1




1





@OrenIshShalom: you can... if you properly escape all $ signs: x=$$(head -n 1 "$$var"); echo "$$x".

– Renaud Pacalet
Jan 4 at 0:48







@OrenIshShalom: you can... if you properly escape all $ signs: x=$$(head -n 1 "$$var"); echo "$$x".

– Renaud Pacalet
Jan 4 at 0:48















1














Don't use variable assignments in recipes. In your command head -n 1 ${var} the expression ${var} expands to nothing and hence head waits on standard input. The following makefile should work:



BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
var=${MYDIR}/m.txt
all:
@echo $(shell head -n 1 ${var})





share|improve this answer
























  • You still want to avoid using $(shell) in the recipe. The echo is also useless.

    – tripleee
    Jan 3 at 12:56


















1














Don't use variable assignments in recipes. In your command head -n 1 ${var} the expression ${var} expands to nothing and hence head waits on standard input. The following makefile should work:



BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
var=${MYDIR}/m.txt
all:
@echo $(shell head -n 1 ${var})





share|improve this answer
























  • You still want to avoid using $(shell) in the recipe. The echo is also useless.

    – tripleee
    Jan 3 at 12:56
















1












1








1







Don't use variable assignments in recipes. In your command head -n 1 ${var} the expression ${var} expands to nothing and hence head waits on standard input. The following makefile should work:



BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
var=${MYDIR}/m.txt
all:
@echo $(shell head -n 1 ${var})





share|improve this answer













Don't use variable assignments in recipes. In your command head -n 1 ${var} the expression ${var} expands to nothing and hence head waits on standard input. The following makefile should work:



BASEDIR = ${HOME}/Downloads
MYDIR = ${BASEDIR}/ddd
var=${MYDIR}/m.txt
all:
@echo $(shell head -n 1 ${var})






share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 3 at 12:20









LeonLeon

21.8k23372




21.8k23372













  • You still want to avoid using $(shell) in the recipe. The echo is also useless.

    – tripleee
    Jan 3 at 12:56





















  • You still want to avoid using $(shell) in the recipe. The echo is also useless.

    – tripleee
    Jan 3 at 12:56



















You still want to avoid using $(shell) in the recipe. The echo is also useless.

– tripleee
Jan 3 at 12:56







You still want to avoid using $(shell) in the recipe. The echo is also useless.

– tripleee
Jan 3 at 12:56




















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%2f54021879%2fmakefile-hangs-when-calling-shell-command-head%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

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith