New answers tagged

1

This is a bare minimum script to get the job done. It makes sure that neither the username nor the uid is already in use. It makes a matching group for each user (with gid=uid) - it doesn't check if the gid or group name already exists (left as an exercise for the reader - hint: use getent group). Note: the script below is untested but I've written ...


2

Lets say your file is named just file. This script will do the job: USERNAME=$(cat file | cut -d: -f1) echo "$USERNAME" ID=$(cat file | cut -d: -f2) echo "$ID" USER_SHELL=$(cat file | cut -d, -f2 | cut -d: -f2) echo "$USER_SHELL" useradd -m -s "$USER_SHELL" -u "$ID" "$USERNAME"


0

from Shawn J. Goff: $VAR vs ${VAR} and to quote or not to quote VAR=$VAR1 is a simplified version of VAR=${VAR1}. There are things the second can do that the first can't, for instance reference an array index (not portable) or remove a substring (POSIX-portable). See the More on variables section of the Bash Guide for Beginners and Parameter ...


1

$VARIABLE and ${VARIABLE} are effectively the same if they are standalone words. But notice the following example, especially in a script VARIABLE=USER echo $VARIABLE you get output USER but when you type echo $VARIABLE1 expecting to get USER1 you get nothing as there is no variable as VARIABLE1 defined But if you use echo ${VARIABLE}1 you ...


0

From my experience I use the && and || to reduce an if statement to a single line. Say we are looking for a file called /root/Sample.txt then the traditional iteration would be as follows in shell: if [ -f /root/Sample.txt ] then echo "file not found" else echo "file found" fi These 6 lines can be reduced to a single line: [[ -f /root/...


3

There's no way to tell for sure whether a file has been renamed. When a file is renamed, its inode number doesn't change. (This may not be true for “exotic” filesystems, such as network filesystems, but it's true for all “native” Unix filesystems.) However the converse is not true: if a file is deleted, a new file may be created with the same inode number. ...


0

File descriptors are created for a program when it opens a file, and is only valid until the program closes it again. So just as you suspected: A different concept. If the file was just renamed the inode(s) won't change, you can use that, but unless renames happen often I doubt it's worth it.


0

If bash is installed on your system, it is probably in your PATH. To run it, type bash in your shell, and you will then be in a bash shell. To make it output the text "Hello world", use the echo builtin: echo "Hello world" To put this into a script which you can then execute, put the following contents into a text file with a name such as hello.sh (the ...


0

Finally this was the solution: cat $type"_"$NAME_DIR"_"$d"_"$2"_"$1".tar.gz."* > $type"_"$NAME_DIR"_"$d"_"$2"_"$1".tar.gz" I haven't escaped the * and I put it outside of "". Thanks to Archemar for his answer. He helps me to find my error.


0

you shouldn't escape *, this will result in shell/bash searching for a litteral star, not expanding filename. try cat $type"_"$NAME_DIR"_"$d"_"$2"_"$1".tar.gz."* > $type"_"$NAME_DIR"_"$d"_"$2"_"$1".tar.gz" edit on a side note I would quote cat ${type}_${NAME_DIR}_${d}_${2}_${1}.tar.gz.* > ${type}_${NAME_DIR}_${d}_${2}_${1}.tar.gz"


0

Someone may have a script (or write one). I do this sort of thing either using zip, or a script which uses gzip or bzip2. Both have provisions for removing the files after the archive is complete. The issues are you can certainly write compressed archives for each directory until the archive is complete, you cannot remove the directory you cannot update ...


3

There are two issues here. First, if you want to replace ; with \;, you need to escape the \. Remember that \ is a special character, it is used to escape things (which is, presumably, precisely why you want to add it before the ;). In order to use it literally, in a substitution, you need to escape it too: $ variable='1;2;3;4' $ echo "${variable//;/\;}" ##...


3

You can not modify the variable inside the for cycle like this in bash. Oh ... you can, but it will not affect the iterations. It is not counted loop as we can be used to from C. Minimal example: #!/bin/bash for i in {1..3} do echo $i i=$((i-1)) echo $i done obviously prints: ./b.sh 1 0 2 1 3 2 You would better be with standard loop with ...


2

A much more readable way to do this sort of this is with a case statement: move='' while [[ -z "$move" ]]; do echo "Please specify paper, scissors, or rock. >" read userinput case "$userinput" in [Rr]*) move="rock" ;; [Pp]*) move="paper" ;; [Ss]*) move="scissors" ;; *)...


1

there are two problems here, one is finding proper terminal setting. I suggest using UTF-8. next try sed -e 's:\,:\,:' -e 's/Décor/D\écor/' VENKAT.TXT you can use multiple replacement using -e ... -e ... you can use any char as separator for find and replace, not just /


2

That's a job for pax. pax is a standard POSIX command; some Linux distributions omit it from the default installation, so you may need to install the package explicitly. You don't get the full power of Perl, just basic sed regex replacement, but that's good enough for your use case. pax -rw -pe -s'|/pars/|/|' -s'|/fts/|/|' -s'|innobase/include|include|' … ...


0

OK, so I managed to get away with plain old sed like this. ls -1 \ storage/{innobase,xtradb}/pars/{pars0grm.cc,pars0grm.y,pars0lex.l,lexyy.cc} \ storage/{innobase,xtradb}/fts/{fts0blex.cc,fts0blex.l,fts0pars.cc,fts0pars.y,fts0tlex.cc,fts0tlex.l} \ storage/innobase/include/fts0[bt]lex.h \ | sed -re 'h; s|/pars/|/|; s|/fts/|/|; s|innobase/...


1

If you know N beforehand, you can use fifo as a semaphore. mkfifo sem; exec 3<>sem rm -f sem Then make each N>1 process read a byte from that &3. Since those bytes won't initially be available, it'll put them to sleep as well. Once N==1 is done sleeping, it can write a N bytes into &3, waking up each process that has been waiting on a byte ...


0

Without seeing a snippet of your code I can only guess that it might be something like this: for k in $(seq $N) do script.sh & done So, in order to wait for the first one to complete before firing off the others you could do something like this: for k in $(seq $N) do script.sh & [[ $k == 1 ]] && wait done If the script ...


1

Unix philosophy: one tool does one thing (very well), then combine tools. I suggest that you use the tools you know. The tools that have all the features and options you need and know/master already. So, use cp, rsync, scp or whatever, then use your favorite rename command.


0

Perl to the rescue: #!/usr/bin/perl use warnings; use strict; my $close_to = 6.1937; my ($close, $lowest); $/ = q(); while (<>) { my @arr = split; if ((! defined $close || abs($arr[1] - $close_to) < abs($close - $close_to)) && $arr[2] > $arr[3] ) { $close = $arr[1]; } if ((! defined $lowest || $...


1

I recommend to use zsh shell for this job: cp *(m-1) /home/oracle/SABARISH/logs/files/ where (m-1) is so called glob qualifier. In this case we select all (*) files modified (m) within (-) last (1) day.


2

You can do something like this: files=$( ls -l --time-style=+%D | grep $(date +%D) | grep -v '^d' | awk '{print $NF}' ) ; for f in $files ; do cp -rf $f /home/oracle/SABARISH/logs/files/ ; done ; sftp {user}@{host}:{remote_dir} <<< 'put /home/oracle/SABARISH/logs/files/*' or similarly: for f in $(ls -l --time-style=+%D | grep $(date +%D) | grep -...


1

It looks to me as if you're being miserly with space characters. You need a space before the {}, and both before and after the \; and after the cp and 'lab4.bak'. You don't need single-quotes around the {} either. The second -exec ... should probably be -exec cp {}.bak /IFT383ss16/Labs/ \; Try this: find . -maxdepth 1 -type f -size +1k \ -exec gzip -...


1

From the bash help on select: select: select NAME [in WORDS ... ;] do COMMANDS; done ... COMMANDS are executed after each selection until a break command is executed The break command you do have in there is breaking the case, not the select. You need to put a break outside the case block. For example: echo "Do u want to check application logs ???...


1

Your first problem is that the block that is to be looped through by a for needs to have a do and done block around it: for f in `cat file` do ... done Your second problem is that the remainder of the loop body (the if statements will not be executed inside the ssh session on the target host(s). You'll have to somehow push the if statements to the ...


2

Yes, you can require both kerberos and public key authentication with AuthenticationMethods sshd option. man 5 sshd_config: AuthenticationMethods Specifies the authentication methods that must be successfully completed for a user to be granted access. This option must be followed by one or more comma-separated lists of authentication ...


1

It is very complex to do this with sed. A more suitable tool is awk or bc. For example, to use bc add another sed to convert the input to a sequence of expressions (10/1) and strings (" ") separated by ";" or newline resulting in the following input for bc: 10/1;" "; 10/1;" "; 1099/100 "N \n" 10/1;" "; 10/1;" "; 1088/100 "E \n" bc will evaluate each ...


1

Using sed and date: sed -n "$(date +'%e')p" textfile.txt date +'%e' gives you the day of the month and this is used as an index for the line sed should print p. /edit: Worked in feedback from the comments.


-1

until ! sleep 60; do echo $(date); command; command; command; done works for me. I don´t need it exactly every 60 seconds "watch" does not watch commands on all systems "watch" can take only one command (or a script file) putting the sleep in the condition instead of the body makes the loop better interruptable (so a claim in a reply to a similar ...


0

Keep your cron on a single server (server1 ?) and then run the scripts remotely from the same controlling machine by setting up an ssh key: ssh server2 /path/to/script This way your jobs are all scheduled in one place, and you aren't recreating crons everywhere.


0

If you just want to check to see if the script is currently running, and if not, run it every hour, you could just do something like: pgrep -x script-name.sh || script-name.sh But you wouldn't want to do this unless you used a unique name for your script--don't use it with "echo" as your example above.


1

I've solved the problem myself using the following solution: sed '/^10.*:/ s/$/ ON/' test_file.txt sed '/^10.*:/ s/$/ OFF/' test_file.txt


1

Did you try something? short example: while read line; do if [[ $line = \10.* ]] ; then echo "$line ON" else echo "$line OFF" fi done As a result: user@:~$ cat testo.txt 10.10.10.10 jsmith1234 [URL] 173.10.10.10 jsmith1234 [URL] user@:~$ bash testo.sh < testo.txt 10.10.10.10 jsmith1234 [URL] ON 173.10.10.10 jsmith1234 [...


-1

cat logfile | while read line do echo ${line} | grep ^"10\." >/dev/null; r=${?} if [ ${r} -eq 0 ] then line=${line}" ON" else line=${line}" OFF" fi echo ${line} done > new_logfile


1

Just remove all cases of IdentityFile and then add them again explicitly: $ perl -i -ne 'next if /IdentityFile/; s#YOURNAME#adminuser\nIdentityFile ~/.ssh/id_rsa#; print' file $ cat file User adminuser IdentityFile ~/.ssh/id_rsa . . . User adminuser IdentityFile ~/.ssh/id_rsa Installing Installing The next if /IdentityFile/ ...


1

Part of the problem is that your template is inconsistent: the first occurrence has an IdentityFile line, while the second does not. You can make it consistent by first deleting the existing IdentityFile lines, and then by adding lines which you want. To delete lines: sed -i '/^IdentityFile /d' filename To add lines, you can do this in sed by matching ...


1

This worked using bash on Ubuntu. It only matches duplicate directories irrespective of depth in the tree. The portion within the $() builds a list of pipe-separated directory names by counting duplicates in the last column of ls -l. This pipe-separated list is filtered using grep over the list of all directories. Also, not accounting for other files (didn't ...


1

Vote me up, because this is the best answer by far! I first found this question, unconvinced by all the answers, here is a much better one, which also allows you to completely obfuscate your bash script, if you are so inclined! It should be self-explanatory. #include <string> #include <unistd.h> template <typename T, typename U> T &...


2

You can use tac to reverse the lines of file and delete 3 lines before matching pattern including line which contains the matching pattern using sed, like this: tac filename | sed '/0 hits/I,+3 d' | tac and if you wanna edit file in place you can use -i option in sed command like, tac filename | sed -i '/0 hits/I,+3 d' filename | tac


0

You can use lftp to do password authentication from a script. Password-less authentication can be very dangerous sometimes. Since I see that you are invoking this script for multiple servers, you will have to manually enter the passwords every time you use sftp. Instead, you can use lftp to put your password inside the script and run it as a cron-job. ...


1

$ sed -e '2,$ s/^host_name/\n&/' ravi.txt | perl -n -e 'if (! m/^$/) { chomp; $line .= $_ . ", " }; if (m/^$/ || eof) { $line =~ s/ +/ /g; # merge multiple spaces into one space $line =~ s/, $//; # strip the trailing comma ...


1

I am sure you can do it much easily in awk, but awk doesn't like me much so here is my take on it using everything but the kitchen sink. Assuming that the data is in a file called file1 export output=; while read line; do if [[ "$line" =~ "host_name" ]]; then export output="${output}\n"; fi; export output="${output}, $line"; done < file1 && echo -...


2

The shell will perform word splitting on $(cat $Errors). That is why you get one word at a time instead of one line at a time. You want a while read... loop: while read -r line; do #Get Error Logs grep "$line" /home/eximlog >> $Elogs done <"$Errors" read is line oriented: it reads one line at a time. Or, this may work for you and it ...


0

I'm developing on GitHub a function that works just like a HashMap Object, shell_map. In order to create "HashMap instances" this function is able create copies of itself under different names. Each new function copy will have a different $FUNCNAME variable. $FUNCNAME then is used to create a namespace for each Map instance. The map keys are global ...


1

There are many issues with your script, but the main one is that you aren't giving any input to your sed command. If you just run sed 's/foo/bar/', then sed will expect input from stdin and will continue to run each time you hit Enter. Since it is getting no input but a newline from you (when you hit Enter, you are sending a blank line which is just a \n ...


3

dch is designed to work one comment at a time. When you're adding changes to the changelog, simply run dch -v ${RELEASE_VER} "comment" multiple times (the -v ${RELEASE_VER} part is only necessary the first time). This will build up a list of changes with a header targeting UNRELEASED; that's the marker dch uses to decide that it should add new comments to ...


0

POSIX sh isn't very good at handling multiple background processes. The basic tool is the wait builtin, which blocks until a background process exits. But wait with no argument waits until all background processes have exited, and returns the exit status of the last process that exited; the exit status of the other subprocesses is lost. You can set a trap ...


2

# launch child process in background launch_child_process & # grab child's pid and store it (use array if several) pid=$! # later, wait for termination wait $pid # show return code from wait, which is actually the return code of the child echo "Child return code:" $? With several children, you can of course loop to wait on each pid and collect the ...


0

If you know in which order the processes will end, approximately, you can use wait <pid> to wait for it to exit, and the wait command will inherit the exit status of the waited-for process. eg if wait $pid1 then echo "$pid1 was ok" else echo "$pid1 failed with code $?" fi If you dont know the order you can wait for any of them with wait -n $pid1 $...



Top 50 recent answers are included