Ubuntu 14.04: crontab -e open a weird file - server

Since I've reboot my server now when I open my crontab file using
crontab -e
Vim is opening a file called:
/tmp/crontab.yWhf4u/crontab
Who is empty...
I would like to know what I did wrong and how I can fix my mistake, please?
My command to reboot the server was
shutdown -r now

crontab -e creates a temporary file that's a copy of your crontab. After you leave the editor, it rereads the temporary file and uses it to update your crontab. (Your actual crontab is in a file in a system directory that you won't have access to without root permissions. Don't try to edit that file directly.)
Apparently your crontab is empty. crontab -l dumps the contents of your crontab to standard output; if that produces no output, it will verify that you have an empty crontab.
You didn't say so, but I presume you thought you had a non-empty crontab. It's easy to clobber your crontab accidentally. For example, if you type crontab with no arguments, it will read a new crontab from standard input; if you then type ctrl-D, it will replace your existing crontab with an empty one.
There's not really a good way to restore your previous crontab. It might exist in a system backup.
In the future, I suggest keeping a copy of your crontab in a separate file, backed up in some way (I use a version control system), and use crontab filename to load the contents of that file into your crontab. That way if you accidentally clobber your crontab, you can easily reload it.

Related

Acquire lock for /etc/passwd file in Bourne shell script

I have an embedded system where user management in /etc/passwd file is done usually automatically with a Bourne shell script. However, it might happen that sometimes /etc/passwd file is edited with a text editor by root user or by passwd utility. Is there a way to program Bourne shell script in a way that it locks the /etc/passwd file during its execution so that other programs are not able to edit the file at the time? Also, this script should detect if /etc/passwd file is not opened by other processes. I could use following solution from Wooledge wiki:
# locking example -- CORRECT
# Bourne
lockdir=/tmp/myscript.lock
if mkdir "$lockdir"
then # directory did not exist, but was created successfully
echo >&2 "successfully acquired lock: $lockdir"
# continue script
else
echo >&2 "cannot acquire lock, giving up on $lockdir"
exit 0
fi
However, this ensures only that two instances of this script are not running simultaneously. I also have a BusyBox lock available which behaves similarly to flock, but again, as far as I can tell, I can't protect other processes editing /etc/passwd file.
The vipw command may provide this for you and you can customize the editor using the EDITOR environment name.
See man vipw for details.
Is there a way to program Bourne shell script in a way that it locks the /etc/passwd file during its execution so that other programs are not able to edit the file at the time?
That is called mandatory file locking and the answer is probably no. In Linux that requires the mand option when the file system is mounted. I would guess that's a nonstarter in your environment, but if it's an option (so to speak) have a look at your favorite resource for how to proceed from there.
It's not shell-script functionality you need. For one process to prevent another from opening a file requires kernel support. Unix programs traditionally use advisory locks, or cooperate some other way. vipw(8) is an example of how that's done.

Is it safe to write a FTP password on a Perl script?

I am writing a Perl script that should connect to a FTP server at some point.
I use Net::FTP module and the login() method to connect, but I am wondering if it is safe to write the password directly in the script. I will chmod the file access to 711, but I am not sure that's enough.
Is there a way to pass the password to the method in a safer way?
If you don't want others on the machine to execute it, chmod 700. There's a number of reasons why it's a good idea for the password to be in a separate file. If you move the password to a config file, that file should be chmod 600.
If you want others on the machine to execute it, chmod 711 isn't going to work. perl must be able to read the script to execute it, so you'd need chmod 755, which means they'll be able to see the password.
The only solution that comes to mind involves file permissions and a set-uid script.
Move the password in a config file.
Create a user to own this application. Let's call it scriptuser. (You could your existing user, but keep in mind the script will be executing as that user.)
chown scriptuser script.pl script.conf.
chmod 600 script.conf
chmod 4755 script.pl
Use script.pl (not perl script.pl) to execute it.
There's no way to securely provide a password in a script, yet allow automatic execution.
You have to store the password somewhere.
It might be better to store it to an external file, so that you do not have to hide away your whole script. For example you might want to have your script reviewed and put to code repository, without the password.

/usr/local/bin/perl5: bad interpreter: Permission denied

I have a unix command
(script) which has a nested perl script in it.
when i run this unix command from command line it works fine.
If I am running same command from a tcl file using exec, i am getting following error:
'sh: /cmdpath/cmd.pl: /usr/local/bin/perl5: bad interpreter: Permission denied'
Any Idea what could be causing this. My tcl code is trying to execute this command several times ( more than 100 times).
Thanks
Ruchi
Almost certainly your Perl script is encoded in DOS/Windows line-ending format, which uses \r\n to terminate lines. Since Unix terminates lines with \n only, the \r is interpreted as belonging to the executable name, so that the kernel tries to run a program named perl5\r and fails.
Deleting the trailing \r on this line should fix the problem.
Alternatively, it may be that the perl5 executable either does not exist at the given path, or exists but lacks the execute permission bit. If you have this executable living somewhere else in the filesystem, update the path on the first line of the script to point to it. To fix the latter problem, run
chmod +x /usr/local/bin/perl5
You will need to be root to do this.
Given the output you are showing, you are likely executing "sh cmd.pl". In turn, sh is trying to execute the perl interpreter.
Why not spawn "/usr/local/bin/perl5 cmd.pl" directly, this will be more efficient, especially if you are doing that hundreds of time.

implement bash command cd in perl

I tried to implement a bash command system("cd /home/user") in perl , but I get an error saying
Can't exec "cd": No such file or directory at temp.pl
Is there a way to change the current working directory to the specified one , and the change remains after the perl script has exited also.
No. A process can't change its parent process's current working directory. Shells implement commands like cd as "builtins", meaning they're a function in the shell itself, and not a separate process that gets run.
You can change the current directory in perl using chdir($dir), and that change will be inherited by child processes — but it won't be passed along to the parent process.
When you want to change the directory inside your Script, you can use the Perl command chdir('dir')
Example:
chdir($dir);
You actually cant modify the directory of the parents process, but you can of the current process
You cannot modify the current working directory of a different process in UNIX, at least not without some serious hackery.
This is why cd is a built-in in all shells. It is not an external program (nor can it be implemented as an external program).
cd is not a process, it is a shell builtin command that changes the current working directory for that shell process.
So use system("sh -c 'cd /my/dir'"). but here system command itself invoke another shall so still it not change directory.
use chdir for that.
cd is not a process, it is a shell builtin command that changes the current working directory for that shell process. So system("sh -c 'cd /cat/bat'") would "succeed", but still wouldn't change the working directory of your perl process; use chdir for that.

How to run perl script from any where (any directory)

I have a perl script exist in the follwoing path (/home/Leen/Desktop/Tools/bin/tool.pl)
Every time I want to run this tool I go to the terminal
>
and then change the directory to
..../bin>
Then I run the perl by writing
..../bin> perl tool.pl file= whatever config= whatever
The problem is that I want to run this perl script without the need to go to the bin folder where it exist . so I can run perl script from any directory and as soon as I enter shell
I went to the etc/environment and I wrote the follwoing
export PERL5LIB=$PERL5LIB:/home/Leen/Desktop/Tools/bin
But when I go to terminal and write the follwoing straight ahead without going to bin folder where tool.pl exist
>perl tool.pl file=... config=...
it says the file "tool.pl" does not exist???
The first argument to the perl program is the path to an executable file. These calls are equivalent:
:~$ perl /home/Leen/Desktop/Tools/bin/tool.pl
:~$ perl ~/Desktop/Tools/bin/tool.pl
:~$ perl ./Desktop/Tools/bin/tool.pl
:~/Desktop/Tools/bin$ perl tool.pl
:~/Desktop/Tools/bin$ perl ./tool.pl
etc.
In the shell the tilde ~ expands to your home directory, and ./ symbolizes the current directory. On *nix shells (including the various terminal emulators on ubuntu), the command prompt ususally is $ in nomal mode, # as root user and seldom %. > Is a secondary command prompt, e.g. when continuing a multiline argument, unlike cmd.exe on Windows.
The PERL5LIB variable determines where Perl looks for modules, not for executable files.
You can set a script as executable via chmod +x FILENAME. You can then call the script without specifying the perl program:
:~/Desktop/Tools/bin$ ./tool.pl
You can modify the PATH variable to change where the shell looks for executables. The PATH usually contains /usr/bin/ and other directories. You can add a directory of your own via
PATH=$PATH:/home/Leen/Desktop/Tools/bin
Add your directory at the end of the PATHes, so you don't overrule other programs.
If you want to set this permanently, you can add this line to the file ~/.bashrc (only for your user and only for the bash shell).
Then you can call your script from anywhere, without a full path name:
:~/foo/bar$ tool.pl
You should consider using a more specific command name in this case, to prevent name clashes.