shell script skipping EOF when boot - shell

I added some shell scripts changing some contents of file in /etc/init.d directory.
#!/bin/bash
set -x
DBMS_ID='testuser'
DBMS_PW1='*****'
CONFIG_EXEC="./some_program"
${CONFIG_EXEC} config <<EOF
yes
127.0.0.1
${DBMS_ID}
${DBMS_PW1}
yes
EOF
cp -f A.txt B.txt
so I expected result below
DB configuration...
HOST : 127.0.0.1
USER : testuser
PASS : ********
PORT : 3306
DB : mysql
UNIX_SOCKET : /tmp/mysql.sock
TESTING CONFIGURATION ...
[ERROR] - Mysql connect error[1045] : Access denied for user 'testuser'#'127.0.0.1' (using password: YES)
Do you want to setup database. [yes/no] : HOST : USER : PASS :
PORT (Default: 3306) : DB (Default: mysql) : UNIX_SOCKET (Default: /var/lib/mysql/mysql.sock) :
TESTING CONFIGURATION ...
[OK]
Done.
+ cp -f A.txt B.txt
but I got some error when reboot
DB configuration...
HOST : 127.0.0.1
USER : testuser
PASS : ********
PORT : 3306
DB : mysql
UNIX_SOCKET : /var/lib/mysql/mysql.sock
TESTING CONFIGURATION ...
[OK]
Do you want to setup database. [yes/no] : HOST : USER : + cp -f A.txt B.txt
some content in EOF block skipped.
why this problem happened?
and How can i fix it?

I found why this happened.
My program (some_program in question) is made with C++, and it uses the tcgetattr function to hide the input password.
On boot, this function leads to the error below, so it looks like skipping. Actually, the problem is caused by this program.
Inappropriate ioctl for device
So it is a different problem with shell.
If someone suffered this problem, or a similar situation, check if some program or script uses tcgetattr or stream-related functions.

Related

How to use a new Windows Terminal app for SSH? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
Improve this question
The Windows Terminal app is advertised as a central hub for all terminal work, so I'm interested in a way to bring my SSH connections into it and replace ancient PuTTY.
You can use a commandline field in your profile configuration to initiate an SSH connection on tab creation.
Step-by-step guide:
Ensure you have an SSH client (try to connect to the server from a Command Prompt tab). #dhgouveia2's post details this step.
Open Settings (Ctrl+,)
Find the "list" array in the "profiles" object
Find a Command Prompt profile ("commandline": "cmd.exe")
Duplicate the profile (copy-paste the whole object, watch for the comma between objects)
Change the "guid" value to a new GUID (for example, from here)
Change the commandline value to "commandline" : "ssh me#my-server -p 22 -i ~/.ssh/id_rsa" (use your own connection command).
Change the profile's "name"
Add an "icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png" item to use a Tux icon (default icons are here)
You should have something like this:
{
"$schema": "https://aka.ms/terminal-profiles-schema",
"profiles":
{
"list":
[
// ...
{
"guid": "{1d43c510-93e8-4960-a18b-e432641e0930}",
"name": "ssh my-server",
"icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png",
"commandline": "ssh me#my-server -p 22 -i ~/.ssh/id_rsa"
}
]
}
}
Save the configuration and enjoy the new item in the New Tab drop-down.
You can use native ssh client from Windows 10,
From powershell
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
# This should return the following output:
Name : OpenSSH.Client~~~~0.0.1.0
State : NotPresent
Name : OpenSSH.Server~~~~0.0.1.0
State : NotPresent
Install the OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
It should return the following output:
Path :
Online : True
RestartNeeded : False
Uninstall the OpenSSH Client
Remove-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
Add the hosts to your ssh config file
From your home folder, go to the .ssh/config file, the folder may not exist if the ssh application has not been used, so it will be necessary to create it on you home folder
C:\Users\%USERPROFILE%\.ssh
#Damo post a very good documentation about the ssh config.
e.g config
Host test
User test
HostName 127.0.0.1
Port 22
IdentityFile ~/.ssh/id_rsa
Windows Terminal
Similar to the #Himura instructions, but instead of using "bash.exe" you will using "ssh.exe".
For connection to the remote host, you can use the hostname from the.ssh/config file e.g ssh.exe test, if you don't want to use a config file, you can use the user#ip ssh.exe test#127.0.0.1 and the password dialog will be promt
Edit your profile.json from the settings on Windows Terminal,
Duplicate a profile
Change the "guid" value to a new GUID
Change the commandline value with ssh.exe, e.g "commandline" : "ssh.exe test"
Change the profile's "name"
e.g
C:\Users\%USERPROFILE%\.ssh\config
Host vagrant
Hostname 127.0.0.1
Port 2222
User vagrant
IdentityFile ~/.ssh/vagrant.key
profile.json
...
{
"acrylicOpacity" : 0.75,
"closeOnExit" : true,
"colorScheme" : "One Half Dark",
"commandline" : "ssh.exe vagrant",
"cursorColor" : "#FFFFFF",
"cursorShape" : "bar",
"fontFace" : "DejaVu Sans Mono for Powerline",
"fontSize" : 10,
"guid" : "{1777cdf0-b2c4-5a63-a204-1111f349ea7c}",
"historySize" : 9001,
"icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png",
"name" : "Vagrant",
"padding" : "0, 0, 0, 0",
"snapOnInput" : true,
"startingDirectory" : "%USERPROFILE%",
"useAcrylic" : true
}
....
If you want to set the new entry as default, search for the defaultProfile key
....
"globals" :
{
"alwaysShowTabs" : true,
"copyOnSelect" : false,
"defaultProfile" : "{1777cdf0-b2c4-5a63-a204-1111f349ea7c}",
"initialCols" : 120,
"initialRows" : 30,
....
If you want to stay in the terminal and easily manage all your ssh connections inside WSL then i would recommend using the built in ssh config management in the ssh command.
Basically you put all your different ssh configurations in to the file ~/.ssh/config
There is a good post documenting the basic use of this here
Hope this helps.
If you want to connect to a machine on Google Compute Engine using Windows Terminal, you can write a script to replace the default command and use ssh instead of putty.exe. More details here.

Bash complete with "#"-sign

I am trying to create an autocomplete script for scp.
The script reads the user and hostname from my .ssh/config file
My .ssh/config file looks like:
Host host1
HostName host1
User userA
port 22
Host host2
HostName host2
User userB
port 22
Host host3
HostName host3
User userB
port 22
My .autocomplete_scp.sh file is:
# SSH
function _scp_completion() {
pcregrep -o -M 'HostName [a-zA-Z.]+[\n\t\s]+User [a-zA-Z]+'
$HOME/.ssh/config | awk 'NR % 2 == 1 { o=$2 ; next } { print $2"#"o}'
}
complete -W "$(_scp_completion)" scp
I source this file in my bashrc.
Now when I type userA and press Tab, the autocomplete function will give me userA#host1. When I type userB and hit Tab, the autocomplete function will give me userB#, but I am not able to get the full string (userB#host2 or userB#host3).
It also doesn't work when I type userA#h and hit the Tab button twice. So it seems to get stuck due to the # sign.
(When I remove the # sign from the _scp_completion function it works fine.)
Any ideas to fix this? Thanks!
The easy way to make it work is to remove '#' from $COMP_WORDBREAKS or Bash would handle # by itself. You can try like this:
COMP_WORDBREAKS=${COMP_WORDBREAKS//#}
complete -W 'userA#host1 userB#host2 userB#host3' scp
According to bash doc:
COMP_WORDBREAKS
The set of characters that the readline library treats as word separators when performing word completion.

Ssh not working when host is taken using grep

When I'm hardcoding i. e.
server1=ip-10.237.40.10-aws-n-myhost
ssh - i /home/<passwordfile> akhil#$server1
It is working,but when I'm greping the host from other file its not working
Eg:
server2=$(grep - e host /home/akhil/configuration. File | awk FS, '{print $2} ' )
echo $server2
ssh - i /home/<passwordfile> akhil#$server2
While printing server 2 is fine, but when it is used in ssh I'm getting a error saying : not known host name.
I want to automate the script with a configuration file so that when ever the cluster changes I could simply change the ip address in configfile instead of changing in all my scripts.
I need help in this.
Thanks

OpenLDAP as a Proxy cache only, no local database

I am trying to get a local LDAP proxy cache running. The idea is this:
Currently a computer (A) is sending all ldap requests to a remote ldap server (L)
Instead of that, there should be a proxy cache "server" running on A to act as an intermediate between A and L. The cache would store all queries and all their attributes (until it is filled up and then it starts "recycling").
OpenLDAP's Proxy Cache Engine looks pretty good, but there is not much information about how to set it up. There is an example config file, but I cannot get it to work.
When connected to the internet, running this command will successfully bind me.
ldapwhoami -vvv -h localhost -D "CN=Melka Martin,OU=something,OU=else,(...),DC=int,DC=somedomain,DC=com" -x -w <passwd>
However, each following request will still pool the remote LDAP server (as shown by sniffing the connection, and when the machine is disconnected from the internet, the local bind fails).
In the slapd output there is a lot of stuff, but the elligible:
56449abd QUERY NOT ANSWERABLE
56449abd QUERY CACHEABLE
This is the current config file, which should cache all the bind requests
database ldap
suffix "dc=int,dc=somedomain,dc=com"
rootdn "cn=admin,dc=int,dc=somedomain,dc=com"
rootpw <something>
uri ldap://dc-04.int.somedomain.com:389
overlay pcache
pcache hdb 100000 1 1000 100
pcacheAttrset 0 *
pcacheTemplate (sn=) 0 3600
pcacheBind (sn=) 0 3600 sub dc=int,dc=somedomain,dc=com
cachesize 200
directory /var/lib/ldap
index objectClass eq
index cn eq,sub
I have created the /var/lib/ldap directory, added a default DB_CONFIG file in there and then edited the slapd.conf file. If there are more things to do to set it up properly, could you instruct me?
I am a little confused about the rootdn/rootpw directives. They are used to write into the remote LDAP server, correct?
Edit: Below here is the original issue, which was resolved by using the full proper DN.
As this is supposed to only be a proxy cache, I shouldn't need to set up a local database. So the config file looks like this:
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
moduleload pcache.la
database ldap
suffix "dc=int,dc=somedomain,dc=com"
rootdn "dc=int,dc=somedomain,dc=com"
uri ldap://dc-04.int.somedomain.com:389
overlay pcache
pcache hdb 100000 1 1000 100
pcacheAttrset 0 *
pcacheTemplate (sn=) 0 3600
cachesize 20
directory /var/lib/ldap
index objectClass eq
index cn eq,sub
Now I would expect that any request to ldap://localhost would mirror to the remote LDAP, if not in the cache.
I use this command to test the auth on the remote server:
ldapwhoami -vvv -h dc-04.int.somedomain.com -p 389 -D melka#somedomain.com -x -w <passwd>
Which works well, I get the auth.
However, when I try to run the same command on localhost:
ldapwhoami -vvv -h localhost -p 389 -D melka#somedomain.com -x -w <passwd>
It fails, saying
ldap_initialize( ldap://localhost:389 )
ldap_bind: Invalid DN syntax (34)
additional info: invalid DN
Slapd is listening on localhost, netstat contains this line:
tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN 10352/slapd
Is there something I am missing?
Thanks
melka#somedomain.com
That may be a DN in the target LDAP system, who knows, but it certainly isn't in OpenLDAP. You need to provide a proper Distinguished Name.

What gems do you recommend to use for this kind of automation?

I have to create a script to manage maintenance pages server for my hosting company.
I will need to do a CLI interface that would act like this (example scenario) :
(here, let's suppose that mcli is the name of the script, 1.1.1.1 the original server address (that host the website, www.exemple.com)
Here I just create the loopback interface on the maintenance server with the original ip address and create the nginx site-specific config file in sites-enabled
$ mcli register www.exemple.com 1.1.1.1
[DEBUG] Adding IP 1.1.1.1 to new loopback interface lo:001001001001
[WARNING] No root directory specified, setting default maintenance page.
[DEBUG] Registering www.exemple.com maintenance page and reloading Nginx: OK
Then when I want to enable the maintenance page and completely shutdown the website:
$ mcli maintenance www.exemple.com
[DEBUG] Connecting to router with SSH: OK
[DEBUG] Setting new route to 1.1.1.1 to maintenance server: OK
[DEBUG] Writing configuration: Ok
Then removing the maintenance page:
$ mcli nomaintenance www.exemple.com
[DEBUG] Connecting to router with SSH: OK
[DEBUG] Removing route to 1.1.1.1: Ok
[DEBUG] Writing configuration: Ok
And I would need a function to see the actual states of the websites
$ mcli list
+------------------+-----------------+------------------+
| Site Name | Server I.P | Maintenance mode |
+------------------+-----------------+------------------+
| www.example.com | 1.1.1.1 | Enabled |
| www.example.org | 1.1.1.2 | Disabled |
+------------------+-----------------+------------------+
$ mcli show www.example.org
Site Name: www.example.org
Server I.P: 1.1.1.1
Maintenance Mode: Enabled
Root Directory : /var/www/maintenance/default/
But I never did this kind of scripting with Ruby. What gems do you recommend for this kind of things ? For command line parsing ? Column/Colorized output ? SSH connection (needed to connect to cisco routers)
Do you recommend me to use a local database (sqlite) to store meta datas (Stages changes, actual states) or do you recommend me to compute on the fly by analyzing nginx/interfaces configuration files and using syslog for monitoring changes done with this script ?
This script will be used at first time for a massive datacenter physical migration, and next for standard usages for scheduled downtimes.
Thank you
First of all, I'd recommend you get a copy of Build awesome command-line applications in Ruby.
That said, you might want to check
GLI command line parsing like git
OptionParser command line parsing
Personally, I'd go for the SQLite approach for storing data, but I'm biased (having a strong SQL background).
Thor is a good gem for handling CLI options. It allows this type of organization in your script:
class Maintenance < Thor
desc "maintenance", "put up maintenance page"
method_option :switch, :aliases => '-s', :type => 'string'
#The method name is the name of the task that would be run => mcli maintenance
def maintenance
#do stuff
end
no_tasks do
#methods that you don't want cli tasks for go here
end
end
Maintenance.start
I don't really have any good suggestions for column/colorized output though.
I definitely recommend using some kind of a database to store states though. Maybe not sqlite, I would probably opt for maybe a redis database that stores key/value pairs with the information you are looking for.
We have similar task. I use next architecture
Small application (C) what generate config file
Add nginx init.d script new switch update_clusters. This script will restart nginx only if config file is changed
update_clusters() {
${CONF_GEN} --outfile=/tmp/nginx_clusters.conf
RETVAL=$?
if [[ "$RETVAL" != "0" ]]; then
return 5
fi
if ! diff ${CLUSTER_CONF_FILE} /tmp/nginx_clusters.conf > /dev/null; then
echo "Cluster configuration changed. Reload service"
mv -f /tmp/nginx_clusters.conf ${CLUSTER_CONF_FILE}
reload
fi
}
Set of bash scripts to add records to database.
Web console to add/modify/delete records in database (extjs+nginx module)

Resources