Tag Info

Hot answers tagged

56

It isn't a shebang, it is just a script that gets run by the default shell. The shell executes the first line //usr/bin/env go run $0 $@ ; exit which causes go to be invoked with the name of this file, so the result is that this file is run as a go script and then the shell exits without looking at the rest of the file. But why start with // instead of ...


8

It runs because by default executable file is assumed to be /bin/sh script. I.e. if you didn't specify any particular shell - it is #!/bin/sh. The // is just ignored in paths - you can consider is at as single '/'. So you can consider that you have shell script with first line: /usr/bin/env go run $0 $@ ; exit What does this line do? It runs 'env' with ...


7

With awk: ps -af -u sas | awk 'BEGIN {RS=" "}; /-Dapp.name/'


5

Most POSIX utilities specify that -- can be used to terminate option arguments: cp -- '-file 1' '-file 2' You can also reference the current directory using the . hard link to the current directory: cp './-file 1' './-file 2'


5

Just repeat the substitution until output doesn't change: $ echo 'A|B|C|D|||E' | sed ':X;s/||/|""|/g;tX' A|B|C|D|""|""|E where :X sets the label X t X go to label X if s/// was successful


5

Your script is a sed script, not a shell script. So you don't need to put sed at the beginning of the line, or put quotes around the commands. Change it to: #!/bin/sed -f s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/192.100.100.100/g


4

The shebang line you've seen may work on some unix variants, but not on Linux. Linux's shebang lines are limited: you can only have one option. The whole string -d -m -S screenName /bin/bash is passed as a single option to screen, instead of being passed as different words. If you want to run a script inside screen and not mess around with multiple files or ...


4

You're not showing the error message you are getting but it's probably grep: unknown devices method That's because, like all or at least most other command line programs, grep assumes that anything that starts with a - is an option and tries to parse it as such. In this case, -D is used to instruct grep on how to deal with a device file (see man grep ...


4

ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*/\1/p'


4

You need spaces around the [ and ], e.g. if [ "$MARK" -ge 0 -a "$MARK" -lt 50 ]; then The way you wrote it, when $MARK is 7, it tries to execute the [7 command instead of passing 7 as an argument to the [ command ([ is just a short name for test). You should also quote the variable. Otherwise, if the user enters a blank line or multiple words, the test ...


4

will a script have different behaviour depending on what type of shell is executing it. In the sense that bash script.sh and ksh script.sh are likely to behave differently, yes. Commonly, that difference will be that one of them works and one gives an error, but there are a range of options. Many simple scripts will have the same behaviour on common ...


3

You just need to create a list of glob matching files, separated by space: for file in .* *; do echo "$file"; done Edit The above one can rewrite in different form using brace expansion for file in {.*,*}; do echo "$file"; done or even shorter for file in {.,}*; do echo "$file"; done Adding path for selected files: for file in /path/{.,}*; ...


3

echo "*file 2" | grep -o ^. prints *. Since you have a command substitution outside double quotes, it undergoes globbing (a.k.a. wildcard matching a.k.a. filename generation) and word splitting. If the current directory is not empty, * expands to the list of files in the current directory. Each file becomes one token in the [ command, which is highly likely ...


3

More complicated than the other answers, but this uses getopt to handle the parsing for you. Yet another alternative. getopt -aql 'Dapp.name:' $(\ ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\ ) | cut -d"'" -f2 your command: ps -af -u sas | grep java | grep -v grep tr -s ' ' "squeezes" multiple spaces into a single space in ...


3

It's because the part where you use the vars is a new set of commands. Use this instead: head somefile | { read A B C D E FOO; echo $A $B $C $D $E $FOO; } Also -n1 is not necessary, read only reads the first line. For better understanding this may help you, it does the same as above: read A B C D E FOO < <(head somefile); echo $A $B $C $D $E $FOO ...


3

According to the screen man pages: screen -d -m Start screen in detached mode. This creates a new session but doesn't attach to it. This is useful for system startup scripts. -S sessionname Set the name of the new session to sessionname. So when I ran the command you provided: screen -dmS name ./script.sh Screen starts a window called name and ...


3

I don't really understand why you would want this but your problem is that you're trying to run a variable instead of evaluating it. Try this instead: #!/bin/csh echo "$*" eval "$*" Then script1 setenv VAR "/user/path" \; ls I don't know csh but the problem seems to be related to having two commands as a variable. This works as expected: setenv aa ...


2

You need to either replace the | with && or let the script output the data to stdout and use |. When using &&, the mail command would only be run when the script exits with 0. When using the pipe character, your script needs to send the data to stdout so the pipe can pass it on to mail. In what you wrote, the script writes data to the file ...


2

What you're showing works as expected on my system. Are you sure you're using bash and not sh? In any case, I tried with dash and with busybox's sh and it worked there too. In the absence of tee, I think the only solution will be to cat $logfile after the command is finished. Another possibility would be to make a link to busybox called tee and attempt to ...


2

To quote from a very useful article wiki.bash-hackers.org: This is because the commands of the pipe run in subshells that cannot modify the parent shell. As a result, the variables of the parent shell are not modified (see article: Bash and the process tree). As the answer has been provided a few times now, an alternative way (using non builtin ...


2

date is not a bash builtin. It is a system utility and that is something on which OSX and Linux differ. OSX uses BSD tools while Linux uses GNU tools. They are similar but not the same. As you have found, on OSX, the -d flag to date controls daylight savings time whereas on Linux, it sets the display time. On OSX, -v adjusts the display date but, on ...


2

Nothing in this script should prevent execution of the next command or return to the shell prompt. What could be giving the impression that the prompt is gone is the output of the remote scripts, which would arrive after return to the shell. To avoid that you could redirect stdout/stderr to some log file. Since the remote commands are run in the background ...


2

If you're fine with the optional arguments being at the end, you can just do this: foo=$1 bar=$2 baz=${3:-default value} That will store the first two arguments in $foo and $bar. If a third argument was provided, it will be stored in $baz; otherwise it will default to default value. You can also just check if the third variable is empty: if [ -z "$3" ]; ...


2

Any time you use ps … | grep … and need to exclude grep from the results, you're doing it wrong. The zeroth rule of parsing the output of ps is to use more reliable tools such as pgrep if available. If you have pgrep, then pgrep -f java lists all the processes running the command java. The option -l adds the command line for each process. To extract the ...


2

Here is one way of counting how many 4, 5, or 6 appear in your number and having bash execute a statement based on whether the result is two or not: $ con1=1457 $ a=${con1//[^456]/}; [ ${#a} -eq 2 ] && echo Yes Yes


2

Try awk with /, ., and (space) as a field separators: awk -F'[/. ]' '{print $1 " " $2 " " $11 " " $13}' file Output: 1 Q0 120411 1 1 Q0 105016 2 1 Q0 149972 3 1 Q0 110688 4


2

The issue is the backticks in your do ... done section. When writing shell script, you do not need to encapsulate blocks (if; then ... fi, while; do ... done, etc) in backticks. Doing so results in the shell evaluating the contents of the backticks, and then executing that content. So the backticks are returning a number (the number of open files), and then ...


1

You need to single quote your here document limit string, otherwise parameter substitution will be enabled. This should work: #!/bin/bash cat server | while read line do /usr/bin/sshpass -e ssh -t -q -o StrictHostKeyChecking=no root@$line <<'EOF' echo successfully logged in $line MYIP=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet ...


1

Method #1 - Using begin/end time You'll typically see it done where you do: begin=$(date +%s) ... do something ... end=$(date +%s) And then subtract the $begin time from the $end time to get the number of seconds that have elapsed. tottime=$(expr $end - $begin) Method #2 - Using the time commands The other method would be to use the time command ...


1

Unquoted newlines in command lines get treated as spaces; that's why you can say things like command1 && command2 Well, sometimes unquoted newlines get treated like semicolons.  But, when you say echo `cat ${log}` all the newlines in the log file get turned into spaces.  You could fix this by saying echo "`cat ${log}`" but why not just say cat ...



Only top voted, non community-wiki answers of a minimum length are eligible