What goes under the hood of `mkvirtualenv` command? - virtualenv

I am curious about what happens under the hood of the mkvirtualenv command and so I am trying to understand how it calls virtualenv.
The lowest hanging fruit is to figure where the virtualenv program is located after installation and where the mkvirtualenv program is located after installation. So:-
Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:07 |~|
calvin$ which mkvirtualenv
Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:10 |~|
calvin$ which virtualenv
/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv
So the strange thing I see here is that which mkvirtualenv does not give any result. Why?
Digging further, in the virtualenvwrapper directory after installing it, I see only 3 python files:-
Calvins-MacBook-Pro.local ttys004 Mon Apr 23 12:28:05 |/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/virtualenvwrapper|
calvin$ ls -la
total 88
drwxr-xr-x 8 root wheel 272 Apr 13 15:07 .
drwxr-xr-x 29 root wheel 986 Apr 15 00:55 ..
-rw-r--r-- 1 root wheel 5292 Apr 13 15:05 hook_loader.py
-rw-r--r-- 1 root wheel 4810 Apr 13 15:07 hook_loader.pyc
-rw-r--r-- 1 root wheel 1390 Apr 13 15:05 project.py
-rw-r--r-- 1 root wheel 2615 Apr 13 15:07 project.pyc
-rw-r--r-- 1 root wheel 7381 Apr 13 15:05 user_scripts.py
-rw-r--r-- 1 root wheel 11472 Apr 13 15:07 user_scripts.pyc
And I suppose that the only reason why mkvirtualenv is now available in my terminal is because I have added in a source/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenvwrapper.sh. So answering the question I asked earlier, this is simply because mkvirtualenv is expressed as a bash function and is available in my terminal because I have sourced virtualenvwrapper.sh in my .bashrc or .bash_profile files.
Digging into the virtualenvwrapper.sh script, I see
# Create a new environment, in the WORKON_HOME.
#
# Usage: mkvirtualenv [options] ENVNAME
# (where the options are passed directly to virtualenv)
#
function mkvirtualenv {
typeset -a in_args
typeset -a out_args
typeset -i i
typeset tst
typeset a
typeset envname
typeset requirements
typeset packages
in_args=( "$#" )
if [ -n "$ZSH_VERSION" ]
then
i=1
tst="-le"
else
i=0
tst="-lt"
fi
while [ $i $tst $# ]
do
a="${in_args[$i]}"
# echo "arg $i : $a"
case "$a" in
-a)
i=$(( $i + 1 ));
project="${in_args[$i]}";;
-h)
mkvirtualenv_help;
return;;
-i)
i=$(( $i + 1 ));
packages="$packages ${in_args[$i]}";;
-r)
i=$(( $i + 1 ));
requirements="${in_args[$i]}";;
*)
if [ ${#out_args} -gt 0 ]
then
out_args=( "${out_args[#]-}" "$a" )
else
out_args=( "$a" )
fi;;
esac
i=$(( $i + 1 ))
done
set -- "${out_args[#]}"
eval "envname=\$$#"
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_virtualenv || return 1
(
[ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
\cd "$WORKON_HOME" &&
"$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$#" &&
[ -d "$WORKON_HOME/$envname" ] && \
virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
)
typeset RC=$?
[ $RC -ne 0 ] && return $RC
# If they passed a help option or got an error from virtualenv,
# the environment won't exist. Use that to tell whether
# we should switch to the environment and run the hook.
[ ! -d "$WORKON_HOME/$envname" ] && return 0
# If they gave us a project directory, set it up now
# so the activate hooks can find it.
if [ ! -z "$project" ]
then
setvirtualenvproject "$WORKON_HOME/$envname" "$project"
fi
# Now activate the new environment
workon "$envname"
if [ ! -z "$requirements" ]
then
pip install -r "$requirements"
fi
for a in $packages
do
pip install $a
done
virtualenvwrapper_run_hook "post_mkvirtualenv"
}
Here's where I don't understand yet - I don't seem to see any direct reference to virtualenv in this bash function. So how exactly does this bash function mkvirtualenv pass the arguments from command line (e.g. mkvirtualenv -p python2.7 --no-site-packages mynewproject) to the python virtualenv program?

So this is the line that does the trick.
(
[ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
\cd "$WORKON_HOME" &&
"$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$#" &&
[ -d "$WORKON_HOME/$envname" ] && \
virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
)
$VIRTUALENVWRAPPER_VIRTUALENV is in fact the location of where the current virtualenv program resides.
In terminal,
Calvins-MacBook-Pro.local ttys004 Mon Apr 23 13:24:14 |~|
calvin$ which $VIRTUALENVWRAPPER_VIRTUALENV
/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv
Mytsery solved.

Related

perl compilation: 'Too many levels of symbolic links'

In Linux, installation of perl is failing while running make test command
t/op/exec ...................................................... # Failed test 17 - at op/exec.t line 114
# $! eq 40, 'Too many levels of symbolic links'
FAILED at test 17
Error is not indicating for which symbolic link it is failing.
Steps Followed:
- Download perl archive from https://www.cpan.org/src/
- [user#hostname perl-5.28.3]$ tar -xvzf perl-5.28.3.tar.gz
- [user#hostname perl-5.28.3]$ cd perl-5.28.3
- [user#hostname perl-5.28.3]$ ./Configure -des -Dinstallprefix=<installation directory>
- [user#hostname perl-5.28.3]$ make
- [user#hostname perl-5.28.3]$ make test
Failed 2 tests out of 2464, 99.92% okay.
../cpan/Time-Local/t/Local.t
op/exec.t
Elapsed: 1317 sec
u=12.87 s=34.02 cu=548.85 cs=488.76 scripts=2464 tests=1158447
make: *** [test] Error 1
[user#hostname perl-5.28.3]$ t/TEST op/exec.t
t/op/exec ... # Failed test 17 - at op/exec.t line 114
# $! eq 40, 'Too many levels of symbolic links'
FAILED at test 17
Failed 1 test out of 1, 0.00% okay.
op/exec.t
Verified same behavior is happening for other perl version also, this is indicating some issue with my installation environment.
Any pointer can be helpful.
Thank you for the pointer #choroba.
Following was the root cause.
In <perl-5.28.3>/t/op/exec.t file, we find the following around line 114:
$rc = system { "lskdfj" } "lskdfj";
unless( ok($rc == 255 << 8 or $rc == -1 or $rc == 256 or $rc == 512) ) {
print "# \$rc == $rc\n";
}
unless ( ok( $! == 2 or $! =~ /\bno\b.*\bfile/i or
$! == 13 or $! =~ /permission denied/i or
$! == 22 or $! =~ /invalid argument/i ) ) {
diag sprintf "\$! eq %d, '%s'\n", $!, $!;
}
In my environment PATH env variable value was
[user#hostname perl-5.28.3]$ echo $PATH
/bin:/usr/lib64/qt-3.3/bin:/bin:/usr/bin:/usr/dev_infra/platform/bin:/usr/dev_infra/generic/bin:/usr/local/bin:/usr/local/ade/bin
Within this PATH, for following paths ls attempt is throwing error 'Too many levels of symbolic links'
[user#hostname perl-5.28.3]$ ls -i /usr/local/bin /usr/local/ade/bin
ls: cannot access /usr/local/bin: Too many levels of symbolic links
ls: cannot access /usr/local/ade/bin: Too many levels of symbolic links
[user#hostname perl-5.28.3]$ ls -ltr /usr/local
lrwxrwxrwx. 1 root root 20 Mar 30 2017 bin -> ./packages/local/bin
lrwxrwxrwx. 1 root root 18 Mar 30 2017 ade -> /usr/local/nde/ade
After removing offending paths from PATH, make test is running successfully
[user#hostname perl-5.28.3]$ export PATH=/bin:/usr/lib64/qt-3.3/bin:/bin:/usr/bin:/usr/dev_infra/platform/bin:/usr/dev_infra/generic/bin
[user#hostname perl-5.28.3]$ make test
All tests successful.
Elapsed: 1611 sec
u=14.47 s=44.63 cu=731.82 cs=575.84 scripts=2474 tests=1209537

sh: add command string ourtput to array

In sh I want to create an array with one element that is the curent date and time formatted with spaces.
$ date +"%b %d %H:%m"
Jun 23 16:06
Here are some things that don't work:
$ date +"%b %d %H:%m"
Jun 23 16:06
$ d=`date +"%b %d %H:%m"`
$ echo $d
Jun 23 16:06
$ arr=($d)
$ echo ${#arr}
3
$ arr=("$d")
$ echo ${#arr}
12
$ arr=("`date +"%b %d %H:%m"`")
$ echo ${#arr}
12
$ arr=(`date +"%b %d %H:%m"`)
$ echo ${#arr}
3
$ echo ${arr[2]}
$
You have a working solution already, but merely misinterpreted the test:
$ d=$(date +"%b %d %H:%m")
$ a=("$d")
$ echo ${#a[*]}
1
$ echo ${#a} # Gives length of ${a[0]}, not number of elements in the array
12
$ a=("$d" "second entry")
$ echo ${a[0]}
Jun 23 16:06
$ echo ${a[1]}
second entry
$ echo ${#a[*]}
2
The strangeness is because these three things are sometimes different:
${#arr}
${#arr[*]}
${#arr[#]}
Also, it's impossible to change IFS
# echo $IFS
# IFS="."
# echo $IFS
#

Linux rpmbuild temporary file error

When runnig rpmbuild with command
rpmbuild -v -ba --sign --clean ~/rpmbuild/SPECS/myspecfile.spec
I get this output:
Enter pass phrase:
Pass phrase is good.
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.6akVI6
+ umask 022
+ cd /home/rpmbuilder/rpmbuild/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ $'\r'
**: command not foundwXWF: line 30:**
error: Bad exit status from /var/tmp/rpm-tmp.6akVI6 (%prep)
So I edited the temporary file /var/tmp/rpm-tmp.6akVI6, searched line 30, and found a single character there:
^M
If I execute the temporary file I get the same error, but it executes the all lines after 30, unlike the rpmbuild that breaks on that line and doesn't continue executing:
sudo sh /var/tmp/rpm-tmp.6akVI6
+ umask 022
+ cd /home/rpmbuilder/rpmbuild/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ $'\r'
**: command not foundkVI6: line 30:**
+ cd /home/rpmbuilder/rpmbuild/BUILD
+ rm -rf mysource-1.0.0
+ /usr/bin/gzip -dc /home/rpmbuilder/rpmbuild/SOURCES/mysource-1.0.0.tar.gz
+ /bin/tar -xvvf -
drwxrwxrwx 0/0 0 2014-11-04 17:10 mysource-1.0.0/
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd mysource-1.0.0
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
If I edit the file and remove line 30 (^M) I am able to run the script with no errors:
sudo sh /var/tmp/rpm-tmp.6akVI6
+ umask 022
+ cd /home/rpmbuilder/rpmbuild/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ cd /home/rpmbuilder/rpmbuild/BUILD
+ rm -rf mysource-1.0.0
+ /usr/bin/gzip -dc /home/rpmbuilder/rpmbuild/SOURCES/mysource-1.0.0.tar.gz
+ /bin/tar -xvvf -
drwxrwxrwx 0/0 0 2014-11-04 17:10 mysource-1.0.0/
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd mysource-1.0.0
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
This suggests me that the rpmbuild is being stopped because of that single character on line 30.
Any hints why is this happening?
Found the answer in here
It seems that files saved on windows, get that character, it is a DOS line ending.
I had my spec file created on windows, so I edited it and did the suggested commands:
:set fileformat=unix
and re-ran rpmbuild and it worked.

Perl: file not recognized [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have this file
lrwxrwxrwx. 1 user user 32 Sep 20 15:43 SingletonLock -> user.hostname.com-22222
I need perl recognizes that file and get its size, What command could I use for this?
I have tried:
my $size = (lstat("/home/user/.config/google-chrome/SingletonLock -> user.hostname.com-22222"))[7];
print $size;
but the variable is empty and $! is No such file or directory
The stat function? Or you might need lstat to get the link information, or readlink to read the name that the symbolic link points to.
Example of stat and lstat working:
$ echo "Petunia" > user.hostname.com-22222
$ ln -s user.hostname.com-22222 SingletonLock
$ ls -l user.* Singl*
lrwxr-xr-x 1 jleffler staff 23 Sep 26 20:24 SingletonLock -> user.hostname.com-22222
-rw-r--r-- 1 jleffler staff 8 Sep 26 20:24 user.hostname.com-22222
$ cat stat.pl
#!/usr/bin/env perl
use strict;
use warnings;
my #names = ( "user.hostname.com-22222", "SingletonLock" );
foreach my $file (#names)
{
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= lstat $file;
printf "lstat: %2d (%.5o) - %s\n", $size, $mode, $file;
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat $file;
printf "stat: %2d (%.5o) - %s\n", $size, $mode, $file;
}
$ perl stat.pl
lstat: 8 (100644) - user.hostname.com-22222
stat: 8 (100644) - user.hostname.com-22222
lstat: 23 (120755) - SingletonLock
stat: 8 (100644) - SingletonLock
$
Give only file name to lstat
my $size = (lstat("/home/user/.config/google-chrome/SingletonLock"))[7];
If you want to get only size of the file you can use -s option in perl
print -s "/home/user/.config/google-chrome/SingletonLock";
or
$filesize = -s $filename;

cpan2rpm cant stat /tmp folder

Im trying to build perl-Heap-Priority for RHEL6. Weired thing is when I run
cpan2rpm Heap::Priority it shows following
...
Tarball extraction: [/root/rpm/SOURCES/Heap-Priority-0.01.tar.gz]
Can't stat /tmp/CldQkErG6r/18:51: No such file or directory
at /usr/bin/cpan2rpm line 392
get_meta(): No such file or directory at /usr/bin/cpan2rpm line 396.
...
Practically this temporary folder is not created. Buy why?
my tmp folder permission is 777
drwxrwxrwt. 3 root root 4096 May 29 16:35 tmp
Known problem, see https://rt.cpan.org/Ticket/Display.html?id=72421. The problem is the space in the user column of the output.
$ tar -tzvf $HOME/rpmbuild/SOURCES/Heap-Priority-0.01.tar.gz |head -1
drwxr-xr-x James Freeman/544 0 2002-05-07 14:51 Heap-Priority-0.01/
Apply the following patch to fix the problem for this module. To get the name, instead of accessing the fifth column, we're accessing the last one. I do not know what else this patch might break, but it should be less wrong than the original code on average.
diff --git a/cpan2rpm b/cpan2rpm
index 28e8b01..6a36b68 100755
--- a/cpan2rpm
+++ b/cpan2rpm
## -1259,7 +1259,7 ## sub untar($) {
;
chomp($_ = qx/$cmd/);
- $_ = (split)[5] unless $zip;
+ $_ = (split)[-1] unless $zip;
$dst .= "/$1" if m|^(\S+)/?|;
$dst =~ s|/*$||; # path shouldn't end in / or tardir gets wiped
$dst =~ s|\./||; # paths in tarballs shouldn't be relative
You could have found out all of this by yourself by using the debugger. Learn to use this tool, it is invaluable.
I think this might be a sightly cleaner way to do it:
--- /usr/bin/cpan2rpm.orig 2017-10-20 14:45:57.000000000 -0700
+++ /usr/bin/cpan2rpm 2017-10-23 12:29:07.006118950 -0700
## -1258,7 +1258,7 ##
my $cmd = $zip
? "unzip -l $_ | grep -P -o '\\S+/\$' |tail -1"
- : "tar -t${z}vf $_ |head -1"
+ : "tar --numeric-owner -t${z}vf $_ |head -1"
;
chomp($_ = qx/$cmd/);