Adding a Windows printer - printers

I need to add 60 label printers to my Windows 7 computer, as network printers. They are all the same printer brand (datamax - O'Neil MP Compact4 MarkII) using the same driver. Each printer is pre configured with IP address and port.
Of course I can add each printer one by one to my Windows, but does anyone know a way to script this into a .bat file or similar?

There are a few ways to do this. If you are adding them as local devices with ports, one of the easiest is to use the built-in vbs scripts on Windows under:
C:\Windows\System32\Printing_Admin_Scripts\en-US
If you need to create the ports you can do this via prnport.vbs then create the printer using prnmngr.vbs. Both of these commands are very straight forward to use:
cscript prnport.vbs -a -r <port name> -h <ip address>
cscript prnmngr.vbs -a -p <printer name> -m <driver name> -r <port name>
Putting this into a large batch file is simple.
I do this so often that I built an Excel Workbook to do it for me. This also allows you to select a remote system / server and poll it for what drivers are installed so you don't mis-type that. You can use this to do the actual work or to create you a batch file that you can later modify.
http://www.ballisticecho.com/articles-and-downloads/best-tool-for-printer-creation-excel-vs-print-management-console

Related

How to set up working X11 forwarding on WSL2 [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.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
When moving from WSL1 to WSL2 many things change; apparently this applies to X11 forwarding as well.
What steps do I need to make in order to use X11 forwarding with WSL2 on Windows 10 as I did with WSL1?
TL;DR:
Add the following to your ~/.bashrc:
export DISPLAY=$(ip route list default | awk '{print $3}'):0
export LIBGL_ALWAYS_INDIRECT=1
Enable Public Access on your X11 server for Windows.*
Add a separate inbound rule for TCP port 6000 to the windows firewall in order to allow WSL access to the X server, as described by the wsl-windows-toolbar-launcher people.
As pointed out by WSL_subreddit_mod on reddit and as you can read in Microsoft's documentation on WSL2, the WSL2 architecture uses virtualized network components. This means that WSL2 has a different IP address than the host machine.
This explains why the X11 forwarding settings of WSL1 cannot simply be transferred to WSL2.
On the Ubuntu Wiki page about WSL you can already find a configuration adapted for WSL2 under Running Graphical Applications. A similar configuration is also suggested by the above mentioned Reddit User, who also contributes another part of the solution: Enable Public Access on the X11 server under Windows.
This means add the following to your ~/.bashrc:
export DISPLAY=$(ip route list default | awk '{print $3}'):0
export LIBGL_ALWAYS_INDIRECT=1
And Enable Public Access on your X11 server for Windows.*
The most important part to enable X11 forwarding for WSL2 on Windows 10 is still missing: the Windows firewall blocks connections via the network interface configured for WSL by default.
A separate inbound rule for TCP port 6000 is required to allow WSL access to the X server. After the rule has been created, as described by the wsl-windows-toolbar-launcher people, the IP address range can be restricted to the WSL subnet in the settings of the newly created rule, under Scope: 172.16.0.0/12.
*: If you use VcXSrv you can enable public access for your X server by disabling Access Control on the Extra Settings:
Or by calling vcxsrv.exe directly with the ac flag: vcxsrv.exe -ac as pointed out by ameeno on the github issue.
Alternatively this SO answer shows how to share keys via .Xauthority files, leaving you with intact access control.
For some people who allowed only for private networks like me,
although they Should have been Both Ticked
It should have stop signs on Windows Defender firewall
Double click it and allow the connection for both private and public,
So all the 4 items should be ticked green.
Then the above answer from #NicolasBrauer was working for me.
Like disabling the access control when you XLaunch and
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=1
I come up with a solution using vxcsrv on windows 10, as others pointed out. Also working on windows 11.
XServer Windows - WSL1 & WSL2:
Install X-Server Windows
https://sourceforge.net/projects/vcxsrv/
Set Display forward in WSL Distro
Configure Display:
If you running WSL1:
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=localhost:0
If you running WSL2:
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
(If you have disabled resolv.conf use this definition: https://stackoverflow.com/a/63092879/11473934)
and then (install x11-apps):
sudo apt update
sudo apt install x11-apps
Start XLaunch on Windows
Multiple Windows
Start no client
disable Native opengl
enable Disable access control
Test it
In wsl: enter xcalc - Calculator should open in Windows10
If everything worked
And you want to persist the settings in your wsl distro. Store them in your ~/.bashrc.
sudo nano ~/.bashrc
Copy the two lines (from Set Display forward in WSL Distro - Configure Display), two the end and save it.
Add it to autostart
Run Dialog see Start XLaunch on Windows
Save configuration
Press Windows + R
Enter: shell:startup
Copy saved configuration: *.launch (Generated in step 2) to this folder (step 4)
Now the XServer will be started with windows startup.
I’m using it for ROS. Works for me.
My XServer isn’t available over internet so its okay to disable access control.
Using /etc/resolv.conf nameserver won't work for me since I disabled resolv.conf generation in /etc/wsl.conf (I have a custom resolv.conf).
Ultimately you want the WSL2 host IP address, which should also be your default route. Here's my ~/.bashrc entry for my Debian WSL2 distro:
export DISPLAY=$(ip route | awk '/^default/{print $3; exit}'):0
How to Setup X11 forwarding in WSL2
This answer assumes that you already have a working XServer and PulseAudio configuration running on your Windows host because you already were using WSL1. (You also may have to add the -ac parameter to the command line to get your XServer of choice to work with WSL2.)
The way that I do this, and to ensure that I get X11 forwarding no matter whether I am using a static IP address or DHCP on the Windows host, or even whether my hostname or network location changes, I add the following to my ~/.bashrc file:
# Get the IP Address of the Windows 10 Host and use it in Environment.
HOST_IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=$HOST_IP:0.0
export NO_AT_BRIDGE=1
export PULSE_SERVER=tcp:$HOST_IP
After doing the above, no matter what my Hostname or IP address of the Host is, it will be placed in the environment each time a BASH session is started in WSL2. Test it by running firefox from the command line and watch a YouTube video. You should be able to hear the sound as well as see the app itself to watch the video. Test by launching other GUI apps from the command line in addition.
What it does: It uses the host command to pull the IPv4 Addresses associated with the Hostname from the output, greps the address that matches the line that contains your Windows Host IPv4 address, strips the rest of the information except for the IP Address, and then awks that and prints it into the variable, with the output trimmed. This then is used to provide the necessary IP address as a string for use in the environment variables that allow for forwarding of X11 and sound output.
Hopefully it works for you if the other methods don't work for you (as they didn't for me).
Most CLI apps can be run either from the BASH Prompt or from Windows Terminal. If you want to make a shortcut, most CLI apps can be set up like either of the following examples (no need for X11 forwarding in such cases except apps like Links2):
C:\Windows\System32\wsl.exe -e htop
C:\Windows\System32\wsl.exe lynx
If you want to create desktop shortcuts for Linux GUI apps, unless you can get the environment variables from your ~/.bashrc file to be used before launching the programs, you will have to create shortcuts using the following template, and put the program name in place of {yourprogram}:
C:\Windows\System32\wsl.exe LIBGL_ALWAYS_INDIRECT=Yes IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') DISPLAY=$IP:0.0 PULSE_SERVER=tcp:$IP {yourprogram}
You do not have to place the full command line for many programs. For PERL-based programs or Python-based programs, you sometimes will have to add the path for PERL and PYTHON, as well as your program's full path, to run such GUI programs in Linux using WSL2. For one of my perl programs, I have to do it this way:
C:\Windows\System32\wsl.exe IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') ; export LIBGL_ALWAYS_INDIRECT=Yes export DISPLAY=$IP:0.0 ; cd /mnt/c/Users/{yourusername}/Desktop ; /usr/bin/perl ~/wget-gui.pl
You may have to experiment a bit to get some apps working properly. For example, you might need to dbus-launch an app, and will need to add that command to the shortcut just before the program name.
C:\Windows\System32\wsl.exe LIBGL_ALWAYS_INDIRECT=Yes IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') DISPLAY=$IP:0.0 PULSE_SERVER=tcp:$IP dbus-launch --exit-with-session gedit
And you might have to use a shorter variable name in some circumstances. Some apps just won't work well, if at all, but this situation is improving over time. Also, don't try to run the above from a Windows Command Prompt or from PowerShell. It will throw errors about 'grep' not being recognized as an internal or external command, etc.
Following is a screenshot of a few Linux GUI apps running on my Windows 10 system, with working X11 forwarding on WSL2.
Copied my answer from this github issue.
The idea is to use the ability to communicate over stdio.
Prerequisite
Just so we can use socat in Windows host, you need a distribution running WSL1. I am sure you can do this in powershell but I didn't have time to research this. Maybe someone can write a stdio->tcp redirector in powershell, then we wouldn't need to have 2 WSL distros.
How to forward X-server connection
Have your favorite X server running on Windows. By default they would listen to port 6000.
In the WSL2 distro, run the following command in the background (ubuntu is the name of the WSL1 distro with socat installed):
mkdir -p /tmp/.X11-unix/
socat UNIX-LISTEN:/tmp/.X11-unix/X0,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d Ubuntu socat - TCP\:localhost\:6000"
Basically this sets up a tunnel from the normal X unix domain socket into the host's port 6000.
How to forward any TCP connection back to host
Let's assume there is a tcp service running at port 5555 on Windows. In the WSL2 distro, run the following command in the background (ubuntu is the name of the WSL1 distro with socat installed):
socat TCP-LISTEN:5555,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d ubuntu socat - TCP\:localhost\:5555"
How to forward any TCP connection from host into WSL2
This is simply doing the same thing, but in the opposite direction. You can run the following in your WSL1 distro:
socat TCP-LISTEN:5555,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d ubuntuwsl2 socat - TCP\:localhost\:5555"
Performance
On my PC, it can handle up to 150MB/s of data so it's not the fastest but fast enough for most applications.
For those who may work with simulation engines such as ROS/Gazebo, Unity and so on, another configuration is needed.
Add these to ~/.bashrc:
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=0
Be sure to enable both Public Access and Private Access for your X11 server in windows. Also disable any access control your X11 server supports.
If you use VcXSrv uncheck Native opengl. Final config for VcXSrv will be like:
Alternative good X11 servers with less difficulties are X410 and MobaXterm. For some details about this configuration refer here and here.
I don't know if that's specific to my configuration but these solutions don't work on my computer. They return the address 192.168.0.254 which is my gateway and not my host computer.
To make it work I had to use the following on my Ubuntu/WSL2 :
export DISPLAY="`ip -4 address | grep -A1 eth0 | grep inet | cut -d' ' -f6 | cut -d/ -f1`:0"
You can get connect to the X server without disabling access control on the server. You use xauth on the server to generate a cookie, then load it into Linux with xauth on the Linux side. You can get the server IP from /etc/resolv.conf. The following is in my .bashrc:
k=$('/mnt/c/Program Files/VcXsrv/xauth.exe' -f 'C:\Users\xxx\Documents\scratch.xauth' -i -n -q 2>/dev/null <<EOF
generate localhost:0 . trusted timeout 604800
list
quit
EOF
)
if [ -n "$k" ]
then
export DISPLAY=$(sed '/^nameserver/ {s/^nameserver\s\s*\([0-9][0-9.]*\)[^0-9.]*$/\1/;p;};d' /etc/resolv.conf):0
xauth -q add $DISPLAY . ${k##* }
export LIBGL_ALWAYS_INDIRECT=true
fi
unset k
Windows 11, and Windows 10 22H2 (build 2311) and later, include WSLg. It just works™ 🎉
Drivers for vGPU (Intel AMD Nvidia) are recommended.
The "System Information" App will tell you your current build number.
Note: WSL1 is not compatible with WSLg. New WSL2 instances will just work™.
Existing WSL2 systems will need to be "updated":
In administrative PowerShell: wsl --update
wsl --shutdown to force a restart of the WSL
Don't forget to remove any other modifications to DISPLAY that you may have made.
I used the following bash to set display:
export DISPLAY=$(powershell.exe -c ipconfig | grep -A4 WSL | tail -1 | awk '{ print $NF }' | tr -d '\r'):0
The solution from https://github.com/microsoft/WSL/issues/4793#issuecomment-588321333 uses VcXsrv as the X-server, and it is where I'm getting this answer (slightly edited for readability). Note that the original is being updated by its author, so don't forget to re-check.
To make it work:
On Windows, with the following, change E:\VcXsrv to where your installation is, and save it as xxx.bat in your Windows startup folder, e.g., C:\Users\Me\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, and you can make it run when boot if you like:
#ECHO OFF
REM Start WSL once to create WSL network interface
wsl exit
REM Find IP for WSL network interface
SET WSL_IF_IP=
CALL :GetIp "vEthernet (WSL)" WSL_IF_IP
ECHO WSL_IF_IP=%WSL_IF_IP%
setx "WSL_IF_IP" "%WSL_IF_IP%"
setx "WSLENV" "WSL_IF_IP/u"
REM Change E:\VcXsrv to your VcXsrv installation folder
START /D "E:\VcXsrv" /B vcxsrv.exe -multiwindow -clipboard -nowgl -ac -displayfd 720
GOTO :EOF
:GetIp ( aInterface , aIp )
(
SETLOCAL EnableExtensions EnableDelayedExpansion
FOR /f "tokens=3 delims=: " %%i IN ('netsh interface ip show address "%~1" ^| findstr IP') DO (
SET RET=%%i
)
)
(
ENDLOCAL
SET "%~2=%RET%"
EXIT /B
)
In WSL, edit ~/.bashrc file to add following lines:
export DISPLAY=$WSL_IF_IP:0
unset LIBGL_ALWAYS_INDIRECT
That's all to make WSL2 work automatically. The idea is to get the private LAN IP of WSL interface on Windows, and use Environment variable to pass it to WSL. WSL then updates this LAN IP to DISPLAY for X-Server connection.
The clipboard works well, too, with this setup. I tested this with a WSL2 install of Ubuntu 20.04 LTS.
I do not want to mess with public access to X server and Windows firewall. My solution is using ssh with X forwarding (works for VirtualBox as well). Additionally, WSL auto-forwards from host to guest listening sockets, so I don't care which IP is actually assigned to guest.
So the steps are these:
Install VcXSrv. Run it with all defaults but set Display number to 0 (-1 will choose 0 if no X instances are already running). Do not start any client in it (this gives a benefit that you can start more apps on the same X server instance).
Open WSL and configure ssh server. For me it's as simple as sudo service ssh start. Create a Windows shortcut with command line: wsl sudo service ssh start.
Install Git for Windows. I actually use it only because its version of ssh is capable of going into background with ssh -f. Windows version of ssh is buggy on this feature, otherwise it's suitable without going to background or with ssh -n.
Configure passwordless login from Git-Bash to the guest. ssh user#127.0.0.1 should work at this point, because the host port is forwarded to the guest.
Verify X forwarding works from Git-Bash: DISPLAY=127.0.0.1:0 ssh -Y user#127.0.0.1 xeyes. I think xeyes is installed with each X distribution.
Install file manager or terminal of your choice in WSL. For example, pcmanfm. Create a Windows shortcut: "C:\Program Files\Git\git-bash.exe" -c "DISPLAY=127.0.0.1:0 ssh -Y -f user#127.0.0.1 'bash -l -c pcmanfm >/dev/null 2>&1'". Here bash -l flag helps setting up environment which may or may not be important depending on apps you run.
Of course, I can do the same without git-bash by using VcXSrv built-in ssh client but it requires converting ssh keys to PuTTY format and I had git-bash already installed. Also, with built-in client display reuse did not work for me.
I would rather set up an ssh server in the guest,
install an X11 server like Xming on the host
and connect to localhost via putty with X11 forwarding.
No fiddling with firewall rules, host IP is not required.
I'm not sure why but none of the above answers worked for me. I'm running on an ROG Zephyrus with AMD and Nvidia graphics which I'm sure caused issues.
The firewall settings described by whme are important, but the linux environment variables did not work for me. I had several entries in the config file labeled as nameserver, non of which allowed connections.
I ended up setting them to:
export DISPLAY=$HOSTNAME:0.0
export LIBGL_ALWAYS_INDIRECT=
I'm using VcXsrv as the X-server. I had to also set the parameters to -nowgl
2021 answer for Windows 10
Check this answer if getting IP from resolv.conf doesn't work.
Find your Windows IP address using following command in your WSL2 (yes, .exe file inside linux):
ipconfig.exe
Use command below to set display (fill YOUR_IP_ADDRESS with your IP):
export DISPLAY=YOUR_IP_ADDRESS:0
Check if your GUI app works correctly.
Automation can be little different for each case but I'll give example:
ipconfig.exe | grep 'IPv4 Address' | grep '10\.' | cut -d ":" -f 2 | cut -d " " -f 2
Explanation: I found all IPv4 addresses (3 IPs in my case). I know that my IP starts only from '10.' so I chose this line using second grep. Next I processed whole line to get the IP only.
I found a solution that worked for me, following:
Set Graphics on WSL2
1. Start ssh service
1.1. Open WSL
1.2. Type: sudo service ssh start
2. Get Windows (WSL net) IP
2.1. Open Powershell
2.2. Type: (ipconfig | Select-String -Pattern 'WSL' -Context 1, 5).Context.PostContext | Select-String -Pattern 'IPv4'
2.3. Get the received IP
3. Set environment variable
3.1. In WSL2 terminal type: export DISPLAY=172.23.64.1:0.0 with the IP of the windows entity (2.3) instead of the place holder
4. Launch Xming
4.1. Open Xlaunch and go with the defaults In Specify parameter settings: Check No Access Control
5. Good luck!
Following link:
https://docs.google.com/document/d/1ao3vjbC3lCDc9kvybOT5PbuGhC4_k4g8LCjxX23VX7E
Here are two articles I wrote that walks through setting up x11 for different types of use cases:
Install a Program With a Graphical User Interface in WSL2: This article walks through installing vcxsrv, adding the environment variables to the bashrc configuration file, and programmatically scheduling vcxsrv to launch with command-line parameters at startup. It also covers installing and launching Firefox as a standalone program in WSL2.
Install Ubuntu Desktop with a Graphical User Interface in WSL2 This article walks through installing vcxsrv, dotNet, genie, and the Ubuntu desktop. It covers creating the scripts that exports the environment variables, launches vcxsrv, starts the gnome desktop environment, and creates the shortcut that ties them all together. It also covers running the Ubuntu desktop, preventing a screen lock bug, and installing the Snap Store.
I also experienced hardships in opening X11 GUIs from WSL.
I had a problem detecting the correct IP and sometimes the X11 server took weird offsets which sometimes appeared as random on 0-17.
I coded the following script to automate this issue, but it has few dependencies:
This was tested and run under CentOS7 image
install X11-apps on your linux distribution to have `xset
install "timeout" app
Execute script by source ./find_display_ip.sh. note the source! You will want to have DISPLAY environment variable on your running shell.
Run the script only through "Windows Terminal" or something that incoprates windows "PATH" inside the WSL shell. This didn't use to be default for me in windows prompt `cmd, for example.
Obviously make sure your X11 server has full access ("xhost +" or "X11 remote access" is full)
Without further a due, this is the script source code:
#!/bin/bash
start_index=$1
start=${start_index:-0}
# check current settings
declare -i stop=0
if [ ! -z "$DISPLAY" ]; then
timeout 1s xset -display $DISPLAY q &> /dev/null;
[[ "$?" -eq 0 ]] && echo "Already Set to $DISPLAY" && stop=1;
fi
# scan displays 0-17
for port in $(seq $start 17);
do
[[ 1 -eq $stop ]] && break;
grp="ipconfig.exe | grep IPv4 | tr -d '\015' | sed 's#.*: \(.*\)\$#\1:${port}.0#;'"
for ipd in $(eval $grp)
do
echo Trying $ipd;
timeout 1s xset -display $ipd q &> /dev/null;
# command was sucessful
[[ "$?" -eq 0 ]] && export DISPLAY=$ipd && echo $ipd was set && stop=1;
##echo "Trying next IP...";
done
done
I found there is a official document fro Ubuntu which is comprehensive for your reference. As we know, this tip will work on Debian/WSL2 as well.
https://wiki.ubuntu.com/WSL
Thanks for Kennyhyun and other people's shares. All of them are some how or some way works on my computer to enable X11 server on WSL2 hosted on Windows10. Since the WSL2 is as a VM not longer be the same infrastructure as WSL1 anymore. It did take me some time to go through it.
Please let me add something briefly about how to make app on WSL2 show up.
run 'ip route' on WLS2 terminal.
ip route
default via a.b.c.1 dev eth0
a.b.c.0/20 dev eth0 proto kernel scope link src x.x.x.x
add this IP address of the "dev eth0" into "export $DISPLAY="
export $DISPLAY=a.b.c.1:0.0
Run xming server.
Then you could run the APP which is running on the WSL2 Linux. But for the X11, you may need to follow the document from Ubuntu.
I've managed to work with the out-of-the-box VcXsrv firewall configuration (i.e., no need to override/disable any firewall rules) by using the LAN adapter IP of the Windows host. Added the below to my ~/.bash_aliases
export DISPLAY=$(pwsh.exe -c ipconfig | grep -A 3 lan | grep IPv4 | head -1 | awk '{ print $NF }'):0
where lan is my Connection-specific DNS Suffix (yours may differ, in which case you should replace it in the command line above).
The following workaround works for me:
Set-NetFirewallProfile -Name $(Get-NetConnectionProfile).NetworkCategory -DisabledInterfaceAliases $(Get-NetAdapter | Where-Object Name -like 'WSL').Name
My mistake was that I took the nameserver of my linux wsl2 instance while my xserver runs on windows. So the DISPLAY variable had to be set to my windows ipv4 address.
Just type ipconfig in powershell or cmd and use the ipv4 ethernet address.

linux print directly to network printer that IS NOT installed

I need to build a simple web based printer server that will print a file to any given printers IP address
Using lp or lpr how can I print a file directly to a network printer by IP address? NOTE: The printer will NOT be setup in CUPS locally as it needs to have the ability to print to any IP address thrown at it.
What I have tried:
lp -d 10.11.234.75 /path/to/file
lpr -P 10.11.234.75 /path/to/file
Both give this: 'The printer or class does not exist.'
Try this:
cat you_file.prn | netcat -w 1 printer_ip 9100
If using bash then:
cat /path/to/file > /dev/tcp/10.11.234.75/9100
What you want to do is probably not feasible. If the printers at the ends of these IP addresses are just random printers, then the server you're building would need to know which driver to use to be able to print to them. If you haven't installed them in any way beforehand then it's not going to work.
If you only want to talk to other Internet Printing Protocol (IPP) servers then it is possible, although not necessarily elegant. I don't know of any other Linux implementations of an IPP client than CUPS, and CUPS requires you to install printers in advance. This can be done very easily though (as explained here). It's the same code to add a normal printer (but you need to know which driver to use) as for an IPP server. Alternatively, you might be able to find another IPP implementation (or write one - it should be fairly simple just to send a document) which doesn't require installing printers.
Here's the code to add an IPP printer to CUPS:
lpadmin -E -p <printer-name> -v http://<ip_address>:631/<dir>/<printer> -L <location> -E
<printer-name> and <location> can be whatever you like, and you need the full network path to the printer.
To add a normal printer:
lpadmin -E -p <printer-name> -v <device-uri> -m <model> -L <location> -E
This is the same, except that you need to give a <model>, which is the driver for the printer. Scrap the first -E if you don't want encryption.
If you want to delete the printer afterwards, use this:
lpadmin -x <printer-name>
I found an old program called tcpsend.c to send a file to a printer at an IP address. Build with gcc -o tcpsend tcpsend.c
$ ./tcpsend
use: tcpsend [-t timeout] host port [files]
-t timeout - try connecting for timeout seconds
tcpsend.c source code
I had success using lp with a hostname and port.
echo foobar | lp -h 10.10.13.37:9100 -
Without specifying a port, i would get
lp: Error - No default destination
If printing a PDF, you can first convert it to PostScript using pdf2ps
pdf2ps file.pdf - | lp -h 10.10.13.37:9100 -
The argument - is used as an alias for standard input or output, letting us pipe the output of postscript straight into standard input of lp.

restricting rsync in daemon mode

I'm trying to run rsync in daemon mode on one machine, called node0. I want the machine to accept connections only from node0 (self) or node1 (some other machine which is defined)
The only path I want to be available for use it /tmp/. So that any read/write operation to any other path should be disallowed, for any originatting machine.
I do not want user restrictions, nor rsync to run over ssh.
I've set up /etc/rsyncd.conf as following:
syslog facility = syslog
max verbosity = 3
log file = /var/log/mylog.log
port = 873
[Proj1]
path = /tmp/
include = /tmp/
exclude = *
comment = some comment
hosts allow = node0, node1
hosts deny = *
max verbosity = 3
log file = /var/log/filedistributer.log
I than execute rsync in daemon mode with the following command:
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf --verbose
Than from node1 I run:
rsync -a test.out node0:/tmp/ and it works correctly.
But if I run: rsync -a max.out node0:/someOtherDir and it also works - where it should not.
If I go to a different machine and run:
rsync -a someFile.out root#node0.MYHOSTNAME:/someOtherDir
It asks me to authorize the ssh key, and enter password for root, after that I copies the file... It should not.
What am I missing? None of my requirments are met:
Rsync uses SSH, when it should not
Rsync does not restrict hosts.
Rsync does not restrict folders
The log file, despite the level 3 verbosity only has one line (per each daemon startup) in the form of:
2013/11/18 12:32:35 [22289] rsyncd version 3.0.6 starting, listening
on port 873
Additionally another problem I encounter is that if I run the rsync command from node0 to node1, it still succeeds, even without me starting rsync in daemon mode on node1.
Your help is appriciated.
Thanks,
Max.
So after some digging what I came up with is that:
By default when running rsync it will try to use ssh as its transport, hence it ssh's to the destination machine and invokes rsync there.
To be used it will require valid credentials on the destination machine. There is no way to avoid this - other than removing the ssh daemon from the destination machine.
In order to restrict rsync from working in this mode, it is actually required to restrict ssh or rsh (or whatever shell is used as transport) from accepting connections from unrelated hosts. Yet it will still be impossible to force the "white list" hosts to operate only on the desired folders in this mode.
My restrictions to rsync in daemon mode using rsyncd.conf are correct and they work, but in order to use tcp as the transport layer and not ssh, it is required to use rsync differently
rsync rsync://node0/Proj1
This will actually make rsync go through a tcp connection and connect to the rsync daemon on the destination.
A very valueble source of information on how rsyn works can be found in the link below:
http://rsync.samba.org/how-rsync-works.html
Did you make sure the config file is actually red by the daemon when launched?
Try for example to deny all hosts and check if the rule applies.

Changing network ip in a bash script started from a NFS-mounted folder

I wrote a simple Bash script to change the network address of a Linux Host:
#!/bin/sh
REMOTE_HOST=192.168.2.127 # Default Host address
NEW_IP=192.168.30.33 # New IP I want to set
NEW_GW=192.168.30.1 # New Gateway I want to set
sudo ifconfig eth0 192.168.2.1 # Moving to the right network...
#ping $REMOTE_HOST -c 3 # I can correctly ping the host here...
ssh-copy-id root#${REMOTE_HOST} > /dev/null # ...for my comfort...
# Setting the network with new values for the IP addr and the GW...
COMMAND="sed -i 's#address *\\([0-9.]\\+\\)#address ${NEW_IP}#' /etc/network/interfaces\
&& sed -i 's#gateway *\\([0-9.]\\+\\)#gateway ${NEW_GW}#' /etc/network/interfaces"
ssh root#${REMOTE_HOST} $COMMAND
# done!
# Now restart the network services:
ssh root#${REMOTE_HOST} "/etc/init.d/networking restart &" & # (Note the 2nd '&' !!!)
# Come back to my old IP
sudo ifconfig eth0 192.168.30.10
sudo route add default gw 192.168.30.1
This script works almost perfectly but:
1) If I run it from my home folder, no problems; if I run it from a NFS shared folder the script hangs for a minute or two before to end correctly
2) If I omit the second '&' when restarting the network on the host the command never returns...
The questions are:
1) What causes the long wait (NFS, different IP address, different gateway)? And is it possible to workaround it?
2) Why it happens? How could I avoid it?
Thanks for any kind of help and sorry for my bad English!
You're restarting networking services, which drops all active connections.
Bash reads the file you're running line by line. Since NFS is a Network File System, this will terminate the connection to the file. So the system waits (can't actually) with executing the lines after networking restart until the connection is re-established.
Instead, you should first make a local copy of the entire script and then run it locally.
You could also code a script for that ;-)

linux execute command remotely

how do I execute command/script on a remote linux box?
say I want to do service tomcat start on box b from box a.
I guess ssh is the best secured way for this, for example :
ssh -OPTIONS -p SSH_PORT user#remote_server "remote_command1; remote_command2; remote_script.sh"
where the OPTIONS have to be deployed according to your specific needs (for example, binding to ipv4 only) and your remote command could be starting your tomcat daemon.
Note:
If you do not want to be prompt at every ssh run, please also have a look to ssh-agent, and optionally to keychain if your system allows it. Key is... to understand the ssh keys exchange process. Please take a careful look to ssh_config (i.e. the ssh client config file) and sshd_config (i.e. the ssh server config file). Configuration filenames depend on your system, anyway you'll find them somewhere like /etc/sshd_config. Ideally, pls do not run ssh as root obviously but as a specific user on both sides, servers and client.
Some extra docs over the source project main pages :
ssh and ssh-agent
man ssh
http://www.snailbook.com/index.html
https://help.ubuntu.com/community/SSH/OpenSSH/Configuring
keychain
http://www.gentoo.org/doc/en/keychain-guide.xml
an older tuto in French (by myself :-) but might be useful too :
http://hornetbzz.developpez.com/tutoriels/debian/ssh/keychain/
ssh user#machine 'bash -s' < local_script.sh
or you can just
ssh user#machine "remote command to run"
If you don't want to deal with security and want to make it as exposed (aka "convenient") as possible for short term, and|or don't have ssh/telnet or key generation on all your hosts, you can can hack a one-liner together with netcat. Write a command to your target computer's port over the network and it will run it. Then you can block access to that port to a few "trusted" users or wrap it in a script that only allows certain commands to run. And use a low privilege user.
on the server
mkfifo /tmp/netfifo; nc -lk 4201 0</tmp/netfifo | bash -e &>/tmp/netfifo
This one liner reads whatever string you send into that port and pipes it into bash to be executed. stderr & stdout are dumped back into netfifo and sent back to the connecting host via nc.
on the client
To run a command remotely:
echo "ls" | nc HOST 4201

Resources