How to use shell command to check SVN check-out files and create links in an directory - bash

Basically my question is how to use bash shell command to do following automatically, so I can track modified files easily.
list svn check-out files
create link files to above files in an directory called "change"
laptop$ svn status -q
M rcms/src/config/ta_show.c
M rcms/src/config/ta_config.c
laptop$ cd change
laptop$ link -s ../rcms/src/config/ta_show.c ta_show.c
laptop$ link -s ../rcms/src/config/ta_config.c ta_config.c
laptop$ ls
lrwxrwxrwx 1 root root 59 Nov 27 12:24 ta_show.c -> ../rcms/src/config/ta_show.c
lrwxrwxrwx 1 root root 59 Nov 27 12:24 ta_config.c -> ../rcms/src/config/ta_config.c
I am thinking to use shell command like below:
$ svn status -q | sed 's/M //' | xargs -I xxx ln -s ***BETWEEN REAL FILE AND BASE FILENAME***

you have two things need to be concerned:
the empty line between each file with svn status 'M'
extract the file name
the awk one liner could do it:
awk '$0{x=$2;gsub(".*/","",x);print "ln -s ../"$2" "x}'
so if you pipe your svn status output to the line above, it print the ln -s command lines for you.
if you want the ln -s lines to get executed, you could either pipe the output to sh (svn status|awk ...|sh) or replace the print with system
at the end i would like to show the output below as an exmple:
kent$ echo "M rcms/src/config/ta_show.c
M rcms/src/config/ta_config.c"|awk '$0{x=$2;gsub(".*/","",x);print "ln -s .."$2" "x}'
ln -s ../rcms/src/config/ta_show.c ta_show.c
ln -s ../rcms/src/config/ta_config.c ta_config.c

Related

Behaviour of /dev/stdout in Cygwin

I have a script (executed with zsh 5.8; but this should not be relevant in this case) in a Cygwin environment, which takes as parameter the name of some output file and writes to this files via redirection in various places, like this:
outfile=$1
: >$outfile # Ensure that the file exists and is empty.
.... do some work
command_x >>$outfile
.... do more work
command_y >>$outfile
... and so on
I would like to modify the behviour of the script in that if no parameter is supplied, the output of the commands goes to standard output instead. I thought that it would be sufficient to modify the script in one line:
outfile=${1:-/dev/stdout}
But nothing is written to stdout. Investigating the case further, I found that instead a regular file named stdout had been created in the /dev directory. It seems that in the Cygwin environment, /dev/stdout does not represent the standard output of the process.
How would I achieve my goal under Cygwin?
UPDATE
As requested by #matzeri, here is a simple testcase:
echo x >/dev/stdout
Expected behaviour: Seeing x on stdout
Real behaviour: A regular file /dev/stdout has been created
on a standard windows installation the /dev/std* are a symlink to the /proc/self/fd/*
ls -l /dev/std*
lrwxrwxrwx 1 Marco Kein 15 Jun 19 2018 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 Marco Kein 15 Jun 19 2018 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 Marco Kein 15 Jun 19 2018 /dev/stdout -> /proc/self/fd/1
if for any reason that is not anymore true they can be recreated
by /etc/postinstall/bash.sh.done script
$ grep self /etc/postinstall/bash.sh.done
/bin/test -h /dev/stdin || ln -sf /proc/self/fd/0 /dev/stdin || result=1
/bin/test -h /dev/stdout || ln -sf /proc/self/fd/1 /dev/stdout || result=1
/bin/test -h /dev/stderr || ln -sf /proc/self/fd/2 /dev/stderr || result=1
/bin/test -h /dev/fd || ln -sf /proc/self/fd /dev/fd || result=1
In that condition the command
$ echo x > /dev/stdout
x
produces the expected output on both Bash and Zsh

While_Run_For_loop_In_bash-Permission-denied

When I'm executing the bash script it said permission denied on a line. below the script and other details.
#!/bin/bash
find /var/opt/gitlab/backups/ -amin +60 |grep tar | cut -d '/' -f 6 >
/tmp/delete-files.txt
chmod +rw /var/opt/gitlab/backups/*.tar
chmod +rw /tmp/delete-files.txt
for i in `/tmp/delete-files.txt`
do
rm -rf /var/opt/gitlab/backups/$i
[root#git opt]# ./asaaa
./asaaa: line 10: /tmp/delete-files.txt: Permission denied'
[root#git opt]#
[root#git opt]# ll /tmp/delete-files.txt
-rw-r--r--. 1 root root 100 Mar 11 12:43 /tmp/delete-files.txt
[root#git opt]#
Help me to sort out this issue.
This line is incorrect:
for i in `/tmp/delete-files.txt`
Backticks mean command substitution. Your script will try to execute /tmp/delete-files.txt. This is not an executable file.
My guess is that what you wanted to do was:
for i in `cat /tmp/delete-files.txt`
Ie. execute cat command to print the contents of the /tmp/delete-files.txt and then loop through each of the printed lines in the for loop.

FTP not working UNIX

hi i have a script where i am performing sudo and going to particular directory,and within that directory editing files name as required. After getting required file name i want to FTP files on windows machine but script after reading FTP commands says-:
-bash: line 19: quote: command not found
-bash: line 20: quote: command not found
-bash: line 21: put: command not found
-bash: line 22: quit: command not found
My ftp is working if i run normally so it is some other problem.Script is below-:
#!/usr/bin/
path=/global/u70/glob
echo password | sudo -S -l
sudo /usr/bin/su - glob << 'EOF'
#ls -lrt
cd "$path"
pwd
for entry in $(ls -r)
do
if [ "$entry" = "ADM" ];then
cd "$entry"
FileName=$(ls -t | head -n1)
echo "$FileName"
FileNameIniKey=$(ls -t | head -n1 | cut -c 12-20)
echo "$FileNameIniKey"
echo "$xmlFileName" >> "$xmlFileNameIniKey.ini"
chmod 755 "$FileName"
chmod 755 "$FileNameIniKey.ini"
ftp -n hostname
quote USER ftp
quote PASS
put "$FileName"
quit
rm "$FileNameIniKey.ini"
fi
done
EOF
You can improve your questions and make them easier to answer and more useful for future readers by including a minimal, self-contained example. Here's an example:
#!/bin/bash
ftp -n mirrors.rit.edu
quote user anonymous
quote pass mypass
ls
When executed, you get a manual FTP session instead of a file listing:
$ ./myscript
Trying 2620:8d:8000:15:225:90ff:fefd:344c...
Connected to smoke.rc.rit.edu.
220 Welcome to mirrors.rit.edu.
ftp>
The problem is that you're assuming that a script is a series of strings that are automatically typed into a terminal. This is not true. It's a series of commands that are executed one after another.
Nothing happens with quote user anonymous until AFTER ftp has exited, and then it's run as a shell command instead of being written to the ftp command.
Instead, specify login credentials on the command line and then include commands in a here document:
ftp -n "ftp://anonymous:passwd#mirrors.rit.edu" << end
ls
end
This works as expected:
$ ./myscript
Trying 2620:8d:8000:15:225:90ff:fefd:344c...
Connected to smoke.rc.rit.edu.
220 Welcome to mirrors.rit.edu.
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
200 Switching to Binary mode.
229 Entering Extended Passive Mode (|||19986|).
150 Here comes the directory listing.
drwxrwxr-x 12 3002 1000 4096 Jul 11 20:00 CPAN
drwxrwsr-x 10 0 1001 4096 Jul 11 21:08 CRAN
drwxr-xr-x 18 1003 1000 4096 Jul 11 18:02 CTAN
drwxrwxr-x 5 89987 546 4096 Jul 10 10:00 FreeBSD
ftp -n "ftp://anonymous:passwd#mirrors.rit.edu" << end
Name or service not known

cd command fails when directory is extracted from windows file

I have one text file in windows that contains lots of directories that I need to extract.
I tried to extract one directory and tried to cd to it in a shell script, but the cd command failed, with prompting cd: /VAR/GPIO/: No such file or directory.
I have confirmed that the directory exists in my local PC and the directory is correct (though it is relative). I have also searched a lot, seems some special windows characters exist in the extract file. I tried to see them with cat -A check and the result is ^[[m^[[K^[[m^[[KVAR/GPIO/$
I don't even know what the meaning of the m^ or [[K.
Could you please help me about this problem? I use Cygwin in Windows 7 64-bit.
Below is my related code for review:
templt_dir=$(cat temp | grep -m 1 "$templt_name" |head -1 | sed -n "s#$templt_name##p" | sed -n "s#\".*##p")
echo $templt_dir ###comment, it runs output: /VAR/GPIO/, that's correct!
cd $templt_dir ###comment, cd error prompts
cat temp | grep -m 1 "$templt_name" |head -1 | sed -n "s#$templt_name##p" | sed -n "s#\".*##p" > check ###comment, for problem checking
Below is the content of the check file:
$ cat -A check
^[[m^[[K^[[m^[[KVAR/GPIO/$
To confirm my directory is correct, below is the results of ls -l on /VAR:
$ ls VAR -l
total 80K
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:11 Analog/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:37 Communication/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:10 GPIO/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:11 HumanInterface/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:11 Memory/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:11 PWM/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:10 Security/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:11 System/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 25 16:25 Timers/
drwxrwx---+ 1 Administrators Domain Users 0 Jun 24 11:10 UniversalDevice/
The error message cd: /VAR/GPIO/: No such file or directory indicates that
the name stored in $templt_dir doesn’t exist.
This is actually due to the string containing non-printing ANSI escape
sequences.
You need to remove these characters from the string containing the directory.
I found the following sed substitution from this Unix and Linux answer
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
which you should include in your pipe command:
templt_dir=$(grep -m 1 "$templt_name" temp | sed -n "s#$templt_name##p; s#\".*##p" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")
Note: I concatenated your two sed substitutions into the one command and I removed the unnecessary cat. I also removed the redundant head -1 since grep -m 1 should only output one line. You can probably combine all the sed substitutions into one: sed -r "s#$templt_name##; s#\".*##; s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" (the -n sed option and p sed command can be left out if there’s only line being processed but I can’t test this without having the original file).
Other ways of using sed to strip ANSI escape sequences are listed at Remove color codes (special characters) with sed.
However, a better long-term fix would be to modify the process which creates the text file listing the directories to not include ANSI Escape codes in its output.

Error building SCP command syntax in read loop

I'm trying to get a list of files copied by SCP from one server to another but the command seems not to be getting build correctly in the read loop.
I have a file called diff_tapes.txt which contains a list of files to be copied as follows:
/VAULT14/TEST_V14/634001
/VAULT14/TEST_V14/634002
/VAULT14/TEST_V14/634003
/VAULT14/TEST_V14/634004
etc etc...
The bash command line I'm using is as follows:
while read line; do scp -p bill#lgrdcpvtsa:$line $line;done < /home/bill/diff_tapes.txt
When I execute that from the command line (I'm running on CentOS so basically Red Hat) I get:
/VAULT14/TEST_V14/634001: No such file or directory
... for every single file.
If I run again adding the -v switch to get more info, I see the following:
debug1: Sending command: scp -v -p -f /VAULT14/TEST_V14/634001
The remote server (lgrdcpvtsa) definitely has the files in question:
[bill#LGRDCPVTSA TEST_V14]$ pwd
/VAULT14/TEST_V14
[bill#LGRDCPVTSA TEST_V14]$ ls -ll
total 207200
-rw------- 1 bill bill 27263700 Apr 26 11:16 634001
-rw------- 1 bill bill 27263700 Apr 26 11:16 634002
-rw------- 1 bill bill 27263700 Apr 26 11:16 634003
-rw------- 1 bill bill 27263700 Apr 26 11:16 634004
It's as though the second time I have $line in the scp command, it's ignored.
Any idea what's wrong with the syntax?
EDIT:
For clarity, the list of files is more likely to be like this:
/VAULT14/634100_V14/634001
/VAULT11/601100_V11/601011
/VAULT12/510200_V12/510192
And /VAULT10 through /VAULT14 exists on both servers, it's just the next folder node might not.
These files are files flagged as being different on local vs remote machine, hence copying from the remote machine which is the correct data source, so a recursive copy won't work here (I think the -r switch was a hangover from an earlier test so I've removed that from the code above).
The error is probably because the local directory /VAULT14/TEST_V14/ does not exist.
You can use the dirname command to get the directory name from the path, create the directory, and then executing the scp command. Example
while read line; do mkdir -p "$(dirname "$line")"; scp -rp bill#lgrdcpvtsa:"$line" "$line";done < /home/bill/diff_tapes.txt
The -p option tells mkdir to create the subdirectories even if the parent does not exist.
EDIT:
This was copying all the files to / so have changed to the following which is working perfectly:
while read line; do mkdir -p "$(dirname "$line")"; scp -p bill#lgrdcpvtsa:"$line" "$line";done < /home/bill/diff_tapes.txt
/VAULT14/TEST_V14/634001: No such file or directory
This is likely because the folder /VAULT14/TEST_V14/ does not exist on the local machine.
Result:
mkdir /VAULT14/TEST14
while read line; do
scp -p bill#lgrdcpvtsa:"$line" "$line"
done < /home/bill/diff_tapes.txt

Resources